/*
 This file is part of the OdinMS Maple Story Server
 Copyright (C) 2008 ~ 2010 Patrick Huy <patrick.huy@frz.cc> 
 Matthias Butz <matze@odinms.de>
 Jan Christian Meyer <vimes@odinms.de>

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License version 3
 as published by the Free Software Foundation. You may not use, modify
 or distribute this program under any other version of the
 GNU Affero General Public License.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package handling.channel.handler;

import client.ISkill;
import client.MapleCharacter;
import client.MapleClient;
import client.MapleStat;
import client.PlayerStats;
import client.SkillFactory;
import client.anticheat.CheatingOffense;
import client.inventory.Equip;
import client.inventory.IEquip;
import client.inventory.IEquip.ScrollResult;
import client.inventory.IItem;
import client.inventory.ItemFlag;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.MapleMount;
import client.inventory.MaplePet;
import client.inventory.MaplePet.PetFlag;
import constants.GameConstants;
import handling.channel.ChannelServer;
import handling.world.MaplePartyCharacter;
import handling.world.World;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.Lock;
import scripting.NPCScriptManager;
import server.*;
import server.AutobanManager;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleShopFactory;
import server.RandomRewards;
import server.Randomizer;
import server.StructRewardItem;
import server.life.MapleLifeFactory;
import server.life.MapleMonster;
import server.maps.*;
import server.maps.FieldLimitType;
import server.maps.MapleMap;
import server.maps.MapleMapItem;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import server.maps.SavedLocationType;
import server.quest.MapleQuest;
import server.shops.HiredMerchant;
import server.shops.IMaplePlayerShop;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packet.MTSCSPacket;
import tools.packet.PetPacket;
import tools.packet.PlayerShopPacket;

public class InventoryHandler {

    public static final void ItemMove(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        if (c.getPlayer().getPlayerShop() != null || c.getPlayer().getConversation() > 0
                || c.getPlayer().getTrade() != null) { // hack
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }

        c.getPlayer().setCurrenttime(System.currentTimeMillis());
        if (c.getPlayer().getCurrenttime() - c.getPlayer().getLasttime() < c.getPlayer().get防止复制时间()) {
            c.getPlayer().dropMessage(5, "请慢点使用.不然会掉线哟！");
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }

        c.getPlayer().setLasttime(System.currentTimeMillis());
        c.getPlayer().updateTick(slea.readInt());
        final MapleInventoryType type = MapleInventoryType.getByType(slea.readByte()); // 04
        final short src = slea.readShort(); // 01 00
        final short dst = slea.readShort(); // 00 00
        final short quantity = slea.readShort();
        if (src < 0 && dst > 0) {
            MapleInventoryManipulator.unequip(c, src, dst);
        } else if (dst < 0) {
            if (dst == -128) {
                c.getPlayer().dropMessage(5, "dst:-128现金戒指位暂停开放(待修复)！");
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            MapleInventoryManipulator.equip(c, src, dst);
        } else if (dst == 0) {
            MapleInventoryManipulator.drop(c, type, src, quantity);
        } else {
            MapleInventoryManipulator.move(c, type, src, dst);
        }
    }

    public static final void ItemSort(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        c.getPlayer().updateTick(slea.readInt());

        final MapleInventoryType pInvType = MapleInventoryType.getByType(slea.readByte());
        if (pInvType == MapleInventoryType.UNDEFINED) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        final MapleInventory pInv = c.getPlayer().getInventory(pInvType); // Mode should correspond with
                                                                          // MapleInventoryType
        boolean sorted = false;

        while (!sorted) {
            final byte freeSlot = (byte) pInv.getNextFreeSlot();
            if (freeSlot != -1) {
                byte itemSlot = -1;
                for (byte i = (byte) (freeSlot + 1); i <= pInv.getSlotLimit(); i++) {
                    if (pInv.getItem(i) != null) {
                        itemSlot = i;
                        break;
                    }
                }
                if (itemSlot > 0) {
                    MapleInventoryManipulator.move(c, pInvType, itemSlot, freeSlot);
                } else {
                    sorted = true;
                }
            } else {
                sorted = true;
            }
        }
        c.getSession().write(MaplePacketCreator.finishedSort(pInvType.getType()));
        c.getSession().write(MaplePacketCreator.enableActions());
        c.getSession().write(MaplePacketCreator.serverNotice(1, "道具集合完毕!"));
    }

    public static final void ItemGather(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        // [41 00] [E5 1D 55 00] [01]
        // [32 00] [01] [01] // Sent after

        c.getPlayer().updateTick(slea.readInt());
        final byte mode = slea.readByte();

        final MapleInventoryType invType = MapleInventoryType.getByType(mode);
        MapleInventory Inv = c.getPlayer().getInventory(invType);
        
        // 屏蔽整理特殊栏
        if (invType == MapleInventoryType.CASH) {
            c.getPlayer().dropMessage("特殊道具暂不开放已种类排列.");
            c.getSession().write(MaplePacketCreator.finishedGather(mode));
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }

        final List<IItem> itemMap = new LinkedList<IItem>();
        for (IItem item : Inv.list()) {
            itemMap.add(item.copy()); // clone all items T___T.
        }
        for (IItem itemStats : itemMap) {
            MapleInventoryManipulator.removeById(c, invType, itemStats.getItemId(), itemStats.getQuantity(), true,
                    false);
        }

        final List<IItem> sortedItems = sortItems(itemMap);
        for (IItem item : sortedItems) {
            MapleInventoryManipulator.addFromDrop(c, item, false);
        }
        c.getSession().write(MaplePacketCreator.finishedGather(mode));
        c.getSession().write(MaplePacketCreator.enableActions());
        itemMap.clear();
        sortedItems.clear();
        c.getSession().write(MaplePacketCreator.serverNotice(1, "以种类排序完毕!"));
    }

    private static final List<IItem> sortItems(final List<IItem> passedMap) {
        final List<Integer> itemIds = new ArrayList<Integer>(); // empty list.
        for (IItem item : passedMap) {
            itemIds.add(item.getItemId()); // adds all item ids to the empty list to be sorted.
        }
        Collections.sort(itemIds); // sorts item ids

        final List<IItem> sortedList = new LinkedList<IItem>(); // ordered list pl0x <3.

        for (Integer val : itemIds) {
            for (IItem item : passedMap) {
                if (val == item.getItemId()) { // Goes through every index and finds the first value that matches
                    sortedList.add(item);
                    passedMap.remove(item);
                    break;
                }
            }
        }
        return sortedList;
    }

    // UseRewardItem 使用奖励道具
    public static final boolean UseRewardItem(final byte slot, final int itemId, final MapleClient c,
            final MapleCharacter chr) {
        final IItem toUse = c.getPlayer().getInventory(GameConstants.getInventoryType(itemId)).getItem(slot);
        c.getSession().write(MaplePacketCreator.enableActions());
        if (toUse != null && toUse.getQuantity() >= 1 && toUse.getItemId() == itemId) {
            if (chr.getInventory(MapleInventoryType.EQUIP).getNextFreeSlot() > -1
                    && chr.getInventory(MapleInventoryType.USE).getNextFreeSlot() > -1
                    && chr.getInventory(MapleInventoryType.SETUP).getNextFreeSlot() > -1
                    && chr.getInventory(MapleInventoryType.ETC).getNextFreeSlot() > -1) {
                final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
                final Pair<Integer, List<StructRewardItem>> rewards = ii.getRewardItem(itemId);

                if (rewards != null && rewards.getLeft() > 0) {
                    boolean rewarded = false;
                    while (!rewarded) {
                        for (StructRewardItem reward : rewards.getRight()) {
                            if (reward.prob > 0 && Randomizer.nextInt(rewards.getLeft()) < reward.prob) { // Total prob
                                if (GameConstants.getInventoryType(reward.itemid) == MapleInventoryType.EQUIP) {
                                    final IItem item = ii.getEquipById(reward.itemid);
                                    if (reward.period > 0) {
                                        item.setExpiration(System.currentTimeMillis() + (reward.period * 60 * 60 * 10));
                                    }
                                    MapleInventoryManipulator.addbyItem(c, item);
                                } else {
                                    MapleInventoryManipulator.addById(c, reward.itemid, reward.quantity, (byte) 0);
                                }
                                MapleInventoryManipulator.removeById(c, GameConstants.getInventoryType(itemId), itemId,
                                        1, false, false);

                                // c.getSession().write(MaplePacketCreator.showRewardItemAnimation(reward.itemid,
                                // reward.effect));
                                // chr.getMap().broadcastMessage(chr,
                                // MaplePacketCreator.showRewardItemAnimation(reward.itemid, reward.effect,
                                // chr.getId()), false);
                                rewarded = true;
                                return true;
                            }
                        }
                    }
                } else {
                    chr.dropMessage(6, "Unknown error.");
                }
            } else {
                chr.dropMessage(6, "你有一個欄位滿了 請空出來再打開");
            }
        }
        return false;
    }

    public static final void QuestKJ(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        if (chr == null || !chr.isAlive() || chr.getCSPoints(2) < 200) {
            chr.dropMessage(1, "你没有足够的抵用卷！");
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        final byte action = (byte) (slea.readByte() + 1);
        short quest = slea.readShort();
        if (quest < 0) { // questid 50000 and above, WILL cast to negative, this was tested.
            quest += 65536; // probably not the best fix, but whatever
        }
        if (chr == null) {
            return;
        }
        final MapleQuest q = MapleQuest.getInstance(quest);
        switch (action) {
        /*
         * case 0: { // Restore lost item chr.updateTick(slea.readInt()); final int
         * itemid = slea.readInt(); MapleQuest.getInstance(quest).RestoreLostItem(chr,
         * itemid); break; } case 1: { // Start Quest final int npc = slea.readInt();
         * q.start(chr, npc); break; }
         */
        case 2: { // Complete Quest
            final int npc = slea.readInt();
            // chr.updateTick(slea.readInt());

            // if (slea.available() >= 4) {
            // q.complete(chr, npc, slea.readInt());
            // } else {
            q.complete(chr, npc);
            // }
            // c.getSession().write(MaplePacketCreator.completeQuest(c.getPlayer(), quest));
            // c.getSession().write(MaplePacketCreator.updateQuestInfo(c.getPlayer(), quest,
            // npc, (byte)14));
            // 6 = start quest
            // 7 = unknown error
            // 8 = equip is full
            // 9 = not enough mesos
            // 11 = due to the equipment currently being worn wtf o.o
            // 12 = you may not posess more than one of this item
            break;
        }
        /*
         * case 3: { // Forefit Quest if (GameConstants.canForfeit(q.getId())) {
         * q.forfeit(chr); } else { chr.dropMessage(1,
         * "You may not forfeit this quest."); } break; } case 4: { // Scripted Start
         * Quest final int npc = slea.readInt(); slea.readInt();
         * NPCScriptManager.getInstance().startQuest(c, npc, quest); break; } case 5: {
         * // Scripted End Quest final int npc = slea.readInt();
         * NPCScriptManager.getInstance().endQuest(c, npc, quest, false);
         * c.getSession().write(MaplePacketCreator.showSpecialEffect(9)); // Quest
         * completion chr.getMap().broadcastMessage(chr,
         * MaplePacketCreator.showSpecialEffect(chr.getId(), 9), false); break; }
         */
        }
        chr.modifyCSPoints(2, -200);

    }

    // UseItem 道具使用
    public static final void UseItem(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        if (chr == null || !chr.isAlive() || chr.getMapId() == 749040100
                || chr.getMap() == null/* || chr.hasDisease(MapleDisease.POTION) */) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        final long time = System.currentTimeMillis();
        if (chr.getNextConsume() > time) {
            chr.dropMessage(5, "You may not use this item yet.");
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);

        if (toUse == null || toUse.getQuantity() < 1 || toUse.getItemId() != itemId) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        if (!FieldLimitType.PotionUse.check(chr.getMap().getFieldLimit()) || chr.getMapId() == 610030600) { // cwk quick
                                                                                                            // hack
            if (MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId()).applyTo(chr)) {
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
                if (chr.getMap().getConsumeItemCoolTime() > 0) {
                    chr.setNextConsume(time + (chr.getMap().getConsumeItemCoolTime() * 1000));
                }
            }

        } else {
            c.getSession().write(MaplePacketCreator.enableActions());
        }
    }

    // UseReturnScroll 使用返回卷轴
    public static final void UseReturnScroll(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        if (!chr.isAlive() || chr.getMapId() == 749040100) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);

        if (toUse == null || toUse.getQuantity() < 1 || toUse.getItemId() != itemId) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        if (!FieldLimitType.PotionUse.check(chr.getMap().getFieldLimit())) {
            if (MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId()).applyReturnScroll(chr)) {
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
            } else {
                c.getSession().write(MaplePacketCreator.enableActions());
            }
        } else {
            c.getSession().write(MaplePacketCreator.enableActions());
        }
    }

    // UseMagnify 鉴定放大镜
    public static final void UseMagnify(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        c.getPlayer().updateTick(slea.readInt());
        final IItem magnify = c.getPlayer().getInventory(MapleInventoryType.USE).getItem((byte) slea.readShort());
        final IItem toReveal = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((byte) slea.readShort());
        if (magnify == null || toReveal == null) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return;
        }
        final Equip eqq = (Equip) toReveal;
        final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        final int reqLevel = ii.getReqLevel(eqq.getItemId()) / 10;
        if (eqq.getState() == 1 && (magnify.getItemId() == 2460003 || (magnify.getItemId() == 2460002 && reqLevel <= 12)
                || (magnify.getItemId() == 2460001 && reqLevel <= 7)
                || (magnify.getItemId() == 2460000 && reqLevel <= 3))) {
            final List<List<StructPotentialItem>> pots = new LinkedList<List<StructPotentialItem>>(
                    ii.getAllPotentialInfo().values());
            int new_state = Math.abs(eqq.getPotential1());
            if (new_state > 7 || new_state < 5) { // luls
                new_state = 5;
            }
            final int lines = (eqq.getPotential2() != 0 ? 3 : 2);
            while (eqq.getState() != new_state) {
                // 31001 = haste, 31002 = door, 31003 = se, 31004 = hb
                for (int i = 0; i < lines; i++) { // 2 or 3 line
                    boolean rewarded = false;
                    while (!rewarded) {
                        StructPotentialItem pot = pots.get(Randomizer.nextInt(pots.size())).get(reqLevel);
                        if (pot != null && pot.reqLevel / 10 <= reqLevel
                                && GameConstants.optionTypeFits(pot.optionType, eqq.getItemId())
                                && GameConstants.potentialIDFits(pot.potentialID, new_state, i)) { // optionType
                            // have to research optionType before making this truely sea-like
                            if (i == 0) {
                                eqq.setPotential1(pot.potentialID);
                            } else if (i == 1) {
                                eqq.setPotential2(pot.potentialID);
                            } else if (i == 2) {
                                eqq.setPotential3(pot.potentialID);
                            }
                            rewarded = true;
                        }
                    }
                }
            }
            c.getSession().write(MaplePacketCreator.scrolledItem(magnify, toReveal, false, true));
            // c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.getPotentialReset(c.getPlayer().getId(),
            // eqq.getPosition()));
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, magnify.getPosition(), (short) 1,
                    false);
        } else {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return;
        }
    }

    public static final boolean UseUpgradeScroll(final byte slot, final byte dst, final byte ws, final MapleClient c,
            final MapleCharacter chr) {
        return UseUpgradeScroll(slot, dst, ws, c, chr, 0);
    }

    public static final boolean UseUpgradeScroll(final byte slot, final byte dst, final byte ws, final MapleClient c,
            final MapleCharacter chr, final int vegas) {
        boolean whiteScroll = false; // white scroll being used?
        boolean legendarySpirit = false; // legendary spirit skill
        final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();

        if ((ws & 2) == 2) {
            whiteScroll = true;
        }

        IEquip toScroll;
        if (dst < 0) {
            toScroll = (IEquip) chr.getInventory(MapleInventoryType.EQUIPPED).getItem(dst);
        } else { // legendary spirit
            legendarySpirit = true;
            toScroll = (IEquip) chr.getInventory(MapleInventoryType.EQUIP).getItem(dst);
        }
        if (toScroll == null) {
            return false;
        }
        final byte oldLevel = toScroll.getLevel();
        final byte oldEnhance = toScroll.getEnhance();
        final byte oldState = toScroll.getState();
        final byte oldFlag = toScroll.getFlag();
        final byte oldSlots = toScroll.getUpgradeSlots();

        boolean checkIfGM = c.getPlayer().isGM();
        IItem scroll = chr.getInventory(MapleInventoryType.USE).getItem(slot);
        if (scroll == null) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        }
        if (!GameConstants.isSpecialScroll(scroll.getItemId()) && !GameConstants.isCleanSlate(scroll.getItemId())
                && !GameConstants.isEquipScroll(scroll.getItemId())
                && !GameConstants.isPotentialScroll(scroll.getItemId())
                && (!GameConstants.is还原类卷轴(scroll.getItemId()))) {
            if (toScroll.getUpgradeSlots() < 1) {
                c.getSession().write(MaplePacketCreator.getInventoryFull());
                return false;
            }
        } else if (GameConstants.isEquipScroll(scroll.getItemId())) {
            if (toScroll.getUpgradeSlots() >= 1 || toScroll.getEnhance() >= 100 || vegas > 0
                    || ii.isCash(toScroll.getItemId())) {
                c.getSession().write(MaplePacketCreator.getInventoryFull());
                return false;
            }
        } else if (GameConstants.isPotentialScroll(scroll.getItemId())) {
            if (toScroll.getState() >= 1 || (toScroll.getLevel() == 0 && toScroll.getUpgradeSlots() == 0) || vegas > 0
                    || ii.isCash(toScroll.getItemId())) {
                c.getSession().write(MaplePacketCreator.getInventoryFull());
                return false;
            }
        }
        if (!GameConstants.canScroll(toScroll.getItemId()) && !GameConstants.isChaosScroll(toScroll.getItemId())) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        }
        if ((GameConstants.isCleanSlate(scroll.getItemId()) || GameConstants.isTablet(scroll.getItemId())
                || GameConstants.isChaosScroll(scroll.getItemId())) && (vegas > 0 || ii.isCash(toScroll.getItemId()))) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        }
        if (GameConstants.isTablet(scroll.getItemId()) && toScroll.getDurability() < 0) { // not a durability item
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        } else if (!GameConstants.isTablet(scroll.getItemId()) && toScroll.getDurability() >= 0) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        }

        IItem wscroll = null;

        // 反作弊与验证
        List<Integer> scrollReqs = ii.getScrollReqs(scroll.getItemId());
        if (scrollReqs.size() > 0 && !scrollReqs.contains(toScroll.getItemId())) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            return false;
        }

        if (whiteScroll) {
            wscroll = chr.getInventory(MapleInventoryType.USE).findById(2340000);
            if (wscroll == null) {
                whiteScroll = false;
            }
        }
        if (scroll.getItemId() == 2049115 && toScroll.getItemId() != 1003068) {
            // ravana
            return false;
        }
        if (GameConstants.isTablet(scroll.getItemId())) {
            switch (scroll.getItemId() % 1000 / 100) {
            case 0: // 1h
                if (GameConstants.isTwoHanded(toScroll.getItemId()) || !GameConstants.isWeapon(toScroll.getItemId())) {
                    return false;
                }
                break;
            case 1: // 2h
                if (!GameConstants.isTwoHanded(toScroll.getItemId()) || !GameConstants.isWeapon(toScroll.getItemId())) {
                    return false;
                }
                break;
            case 2: // armor
                if (GameConstants.isAccessory(toScroll.getItemId()) || GameConstants.isWeapon(toScroll.getItemId())) {
                    return false;
                }
                break;
            case 3: // accessory
                if (!GameConstants.isAccessory(toScroll.getItemId()) || GameConstants.isWeapon(toScroll.getItemId())) {
                    return false;
                }
                break;
            }
        } else if (!GameConstants.isAccessoryScroll(scroll.getItemId())
                && !GameConstants.isChaosScroll(scroll.getItemId()) && !GameConstants.isCleanSlate(scroll.getItemId())
                && !GameConstants.isEquipScroll(scroll.getItemId())
                && !GameConstants.isPotentialScroll(scroll.getItemId())) {
            if (!ii.canScroll(scroll.getItemId(), toScroll.getItemId())) {
                return false;
            }
        }
        if (GameConstants.isAccessoryScroll(scroll.getItemId()) && !GameConstants.isAccessory(toScroll.getItemId())) {
            return false;
        }
        if (scroll.getQuantity() <= 0) {
            return false;
        }

        if (legendarySpirit && vegas == 0) {
            if (chr.getSkillLevel(SkillFactory.getSkill(1003)) <= 0
                    && chr.getSkillLevel(SkillFactory.getSkill(10001003)) <= 0
                    && chr.getSkillLevel(SkillFactory.getSkill(20001003)) <= 0
                    && chr.getSkillLevel(SkillFactory.getSkill(20011003)) <= 0
                    && chr.getSkillLevel(SkillFactory.getSkill(30001003)) <= 0) {
                AutobanManager.getInstance().addPoints(c, 50, 120000,
                        "Using the Skill 'Legendary Spirit' without having it.");
                return false;
            }
        }

        // 卷成功, 失败, 诅咒
        final IEquip scrolled = (IEquip) ii.scrollEquipWithId(toScroll, scroll, whiteScroll, chr, vegas, checkIfGM);
        ScrollResult scrollSuccess;
        if (scrolled == null) {
            scrollSuccess = IEquip.ScrollResult.CURSE;
        } else if (scrolled.getLevel() > oldLevel || scrolled.getEnhance() > oldEnhance
                || scrolled.getState() > oldState || scrolled.getFlag() > oldFlag) {
            scrollSuccess = IEquip.ScrollResult.SUCCESS;
        } else if ((GameConstants.isCleanSlate(scroll.getItemId()) && scrolled.getUpgradeSlots() > oldSlots)) {
            scrollSuccess = IEquip.ScrollResult.SUCCESS;
        } else {
            scrollSuccess = IEquip.ScrollResult.FAIL;
        }

        // 更新道具
        chr.getInventory(MapleInventoryType.USE).removeItem(scroll.getPosition(), (short) 1, false);
        if (whiteScroll) {
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, wscroll.getPosition(), (short) 1, false,
                    false);
        }

        if (scrollSuccess == IEquip.ScrollResult.CURSE) {
            c.getSession().write(MaplePacketCreator.scrolledItem(scroll, toScroll, true, false));
            if (dst < 0) {
                chr.getInventory(MapleInventoryType.EQUIPPED).removeItem(toScroll.getPosition());
            } else {
                chr.getInventory(MapleInventoryType.EQUIP).removeItem(toScroll.getPosition());
            }
        } else if (vegas == 0) {
            c.getSession().write(MaplePacketCreator.scrolledItem(scroll, scrolled, false, false));
        }

        chr.getMap().broadcastMessage(chr,
                MaplePacketCreator.getScrollEffect(c.getPlayer().getId(), scrollSuccess, legendarySpirit), vegas == 0);

        // equipped item was scrolled and changed
        if (dst < 0 && (scrollSuccess == IEquip.ScrollResult.SUCCESS || scrollSuccess == IEquip.ScrollResult.CURSE)
                && vegas == 0) {
            chr.equipChanged();
        }
        return true;
    }

    // UseCatchItem 使用捕捉道具
    public static final void UseCatchItem(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemid = slea.readInt();
        final MapleMonster mob = chr.getMap().getMonsterByOid(slea.readInt());
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);

        if (toUse != null && toUse.getQuantity() > 0 && toUse.getItemId() == itemid && mob != null) {
            switch (itemid) {
            case 2270004: { // 净化之珠
                final MapleMap map = chr.getMap();

                if (mob.getHp() <= mob.getMobMaxHp() / 2) {
                    map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 1));
                    map.killMonster(mob, chr, true, false, (byte) 0);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, false, false);
                    MapleInventoryManipulator.addById(c, 4001169, (short) 1, (byte) 0);
                } else {
                    map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 0));
                    chr.dropMessage(5, "怪物的生命力还很强大, 无法捕捉.");
                }
                break;
            }
            case 2270002: { // 速成石
                final MapleMap map = chr.getMap();

                if (mob.getHp() <= mob.getMobMaxHp() / 2) {
                    c.getPlayer().getMap()
                            .broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 1));
                    // map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid,
                    // (byte) 1));
                    map.killMonster(mob, chr, true, false, (byte) 0);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, false, false);
                    c.getPlayer().setAPQScore(c.getPlayer().getAPQScore() + 1);
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator
                            .updateAriantPQRanking(c.getPlayer().getName(), c.getPlayer().getAPQScore(), false));
                } else {
                    c.getPlayer().getMap()
                            .broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 0));
                    // map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid,
                    // (byte) 0));
                    chr.dropMessage(5, "怪物的生命力还很强大, 无法捕捉.");
                }
                break;
            }
            case 2270000: { // 费洛蒙香水
                if (mob.getId() != 9300101) {
                    break;
                }
                final MapleMap map = c.getPlayer().getMap();

                map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 1));
                map.killMonster(mob, chr, true, false, (byte) 0);
                MapleInventoryManipulator.addById(c, 1902000, (short) 1, null, (byte) 0);
                MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, false, false);
                break;
            }
            case 2270003: { // 克里夫的魔法杖
                if (mob.getId() != 9500320) {
                    break;
                }
                final MapleMap map = c.getPlayer().getMap();

                if (mob.getHp() <= mob.getMobMaxHp() / 2) {
                    map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 1));
                    map.killMonster(mob, chr, true, false, (byte) 0);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, false, false);
                } else {
                    map.broadcastMessage(MaplePacketCreator.catchMonster(mob.getId(), itemid, (byte) 0));
                    chr.dropMessage(5, "The monster has too much physical strength, so you cannot catch it.");
                }
                break;
            }
            }
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    // UseMountFood 使用宠物食品
    public static final void UseMountFood(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemid = slea.readInt(); // 2260000 usually恢复疲劳补药
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);
        final MapleMount mount = chr.getMount();

        if (toUse != null && toUse.getQuantity() > 0 && toUse.getItemId() == itemid && mount != null) {
            final int fatigue = mount.getFatigue();

            boolean levelup = false;
            mount.setFatigue((byte) -30);

            if (fatigue > 0) {
                mount.increaseExp();
                final int level = mount.getLevel();
                if (mount.getExp() >= GameConstants.getMountExpNeededForLevel(level + 1) && level < 31) {
                    mount.setLevel((byte) (level + 1));
                    levelup = true;
                }
            }
            chr.getMap().broadcastMessage(MaplePacketCreator.updateMount(chr, levelup));
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    public static final void UseScriptedNPCItem(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);
        long expiration_days = 0;
        int mountid = 0;

        if (toUse != null && toUse.getQuantity() >= 1 && toUse.getItemId() == itemId) {
            switch (toUse.getItemId()) {
            case 2430007: // 空罗盘
            {
                final MapleInventory inventory = chr.getInventory(MapleInventoryType.SETUP);
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (byte) 1, false);

                if (inventory.countById(3994102) >= 20 // Compass Letter "North"
                        && inventory.countById(3994103) >= 20 // Compass Letter "South"
                        && inventory.countById(3994104) >= 20 // Compass Letter "East"
                        && inventory.countById(3994105) >= 20) { // Compass Letter "West"
                    MapleInventoryManipulator.addById(c, 2430008, (short) 1, (byte) 0); // Gold Compass
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.SETUP, 3994102, 20, false, false);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.SETUP, 3994103, 20, false, false);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.SETUP, 3994104, 20, false, false);
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.SETUP, 3994105, 20, false, false);
                } else {
                    MapleInventoryManipulator.addById(c, 2430007, (short) 1, (byte) 0); // Blank Compass
                }
                NPCScriptManager.getInstance().start(c, 2084001);
                break;
            }
            case 2430008: // 黄金罗盘
            {
                chr.saveLocation(SavedLocationType.RICHIE);
                MapleMap map;
                boolean warped = false;

                for (int i = 390001000; i <= 390001004; i++) {
                    map = c.getChannelServer().getMapFactory().getMap(i);

                    if (map.getCharactersSize() == 0) {
                        chr.changeMap(map, map.getPortal(0));
                        warped = true;
                        break;
                    }
                }
                if (warped) { // Removal of gold compass
                    MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, 2430008, 1, false, false);
                } else { // Or mabe some other message.
                    c.getPlayer().dropMessage(5, "All maps are currently in use, please try again later.");
                }
                break;
            }
            case 2430112: // 神奇魔方碎片
                if (c.getPlayer().getInventory(MapleInventoryType.USE).getNumFreeSlot() >= 1) {
                    if (c.getPlayer().getInventory(MapleInventoryType.USE).countById(2430112) >= 25) {
                        if (MapleInventoryManipulator.checkSpace(c, 2049400, 1, "") && MapleInventoryManipulator
                                .removeById(c, MapleInventoryType.USE, 2430112, 25, true, false)) {
                            MapleInventoryManipulator.addById(c, 2049400, (short) 1, (byte) 0);
                        } else {
                            c.getPlayer().dropMessage(5, "Please make some space.");
                        }
                    } else if (c.getPlayer().getInventory(MapleInventoryType.USE).countById(2430112) >= 10) {
                        if (MapleInventoryManipulator.checkSpace(c, 2049400, 1, "") && MapleInventoryManipulator
                                .removeById(c, MapleInventoryType.USE, 2430112, 10, true, false)) {
                            MapleInventoryManipulator.addById(c, 2049401, (short) 1, (byte) 0);
                        } else {
                            c.getPlayer().dropMessage(5, "Please make some space.");
                        }
                    } else {
                        c.getPlayer().dropMessage(5,
                                "There needs to be 10 Fragments for a Potential Scroll, 25 for Advanced Potential Scroll.");
                    }
                } else {
                    c.getPlayer().dropMessage(5, "Please make some space.");
                }
                break;
            case 2430036: // 黑鳄鱼1天使用券
                mountid = 1027;
                expiration_days = 1;
                break;
            case 2430037: // 男男机车1天使用
                mountid = 1028;
                expiration_days = 1;
                break;
            case 2430038: // 女女机车1天使用券
                mountid = 1029;
                expiration_days = 1;
                break;
            case 2430039: // 筋斗云1天使用券
                mountid = 1030;
                expiration_days = 1;
                break;
            case 2430040: // balrog 1 day
                mountid = 1031;
                expiration_days = 1;
                break;
            case 2430053: // croco 30 day
                mountid = 1027;
                expiration_days = 1;
                break;
            case 2430054: // black scooter 30 day
                mountid = 1028;
                expiration_days = 30;
                break;
            case 2430055: // pink scooter 30 day
                mountid = 1029;
                expiration_days = 30;
                break;
            case 2430056: // mist rog 30 day
                mountid = 1035;
                expiration_days = 30;
                break;
            // race kart 30 day? unknown 2430057
            case 2430072: // ZD tiger 7 day
                mountid = 1034;
                expiration_days = 7;
                break;
            case 2430073: // lion 15 day
                mountid = 1036;
                expiration_days = 15;
                break;
            case 2430074: // unicorn 15 day
                mountid = 1037;
                expiration_days = 15;
                break;
            case 2430075: // low rider 15 day
                mountid = 1038;
                expiration_days = 15;
                break;
            case 2430076: // red truck 15 day
                mountid = 1039;
                expiration_days = 15;
                break;
            case 2430077: // gargoyle 15 day
                mountid = 1040;
                expiration_days = 15;
                break;
            case 2430080: // shinjo 20 day
                mountid = 1042;
                expiration_days = 20;
                break;
            case 2430082: // orange mush 7 day
                mountid = 1044;
                expiration_days = 7;
                break;
            case 2430091: // nightmare 10 day
                mountid = 1049;
                expiration_days = 10;
                break;
            case 2430092: // yeti 10 day
                mountid = 1050;
                expiration_days = 10;
                break;
            case 2430093: // ostrich 10 day
                mountid = 1051;
                expiration_days = 10;
                break;
            case 2430101: // pink bear 10 day
                mountid = 1052;
                expiration_days = 10;
                break;
            case 2430102: // transformation robo 10 day
                mountid = 1053;
                expiration_days = 10;
                break;
            case 2430103: // chicken 30 day
                mountid = 1054;
                expiration_days = 30;
                break;
            case 2430117: // lion 1 year
                mountid = 1036;
                expiration_days = 365;
                break;
            case 2430118: // red truck 1 year
                mountid = 1039;
                expiration_days = 365;
                break;
            case 2430119: // gargoyle 1 year
                mountid = 1040;
                expiration_days = 365;
                break;
            case 2430120: // unicorn 1 year
                mountid = 1037;
                expiration_days = 365;
                break;
            case 2430136: // owl 30 day
                mountid = 1069;
                expiration_days = 30;
                break;
            case 2430137: // 猫头鹰骑宠1年权
                mountid = 1069;
                expiration_days = 365;
                break;
            case 2430201: // 兔子骑宠60日券
                mountid = 1096;
                expiration_days = 60;
                break;
            case 2430228: // 兔兔加油骑宠（60天权）
                mountid = 1101;
                expiration_days = 60;
                break;
            case 2430229: // 兔车 60天 权
                mountid = 1102;
                expiration_days = 60;
                break;
            }
        }
        if (mountid > 0) {
            mountid += (GameConstants.isAran(c.getPlayer().getJob()) ? 20000000
                    : (GameConstants.isEvan(c.getPlayer().getJob()) ? 20010000
                            : (GameConstants.isKOC(c.getPlayer().getJob()) ? 10000000
                                    : (GameConstants.isResist(c.getPlayer().getJob()) ? 30000000 : 0))));
            if (c.getPlayer().getSkillLevel(mountid) > 0) {
                c.getPlayer().dropMessage(5, "你已经拥有了这个技能.");
            } else if (expiration_days > 0) {
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (byte) 1, false);
                c.getPlayer().changeSkillLevel(SkillFactory.getSkill(mountid), (byte) 1, (byte) 1,
                        System.currentTimeMillis() + (long) (expiration_days * 24 * 60 * 60 * 1000));
                c.getPlayer().dropMessage(5, "已经达到的技能.");
            }
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    public static void UsePenguinBox(SeekableLittleEndianAccessor slea, MapleClient c) {
        final List<Integer> gift = new ArrayList<Integer>();
        final byte slot = (byte) slea.readShort();
        final int item = slea.readInt();
        final IItem toUse = c.getPlayer().getInventory(MapleInventoryType.USE).getItem((short) slot);

        if (toUse.getItemId() != item) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() <= 1) {
            c.getPlayer().dropMessage(1, "背包已满，无法获得物品");
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }

        switch (item) {
        case 2022570:// - 企鹅王的战士武器箱子 - 装着企鹅王的战士武器的箱子。
            gift.add(1302119);// - 企鹅王的弯刀 - (无描述)
            gift.add(1312045);// - 企鹅王的大斧 - (无描述)
            gift.add(1322073);// - 企鹅王的骑士锤 - (无描述)
            break;
        case 2022571:// - 企鹅王的魔法师武器箱子 - 装着企鹅王的魔法师武器的箱子。
            gift.add(1372053);// - 企鹅王的法师短杖 - (无描述)
            gift.add(1382070);// - 企鹅王的翡翠之杖 - (无描述)
            break;
        case 2022572:// - 企鹅王的弓箭手武器箱子 - 装着企鹅王的弓箭手武器的箱子。
            gift.add(1462066);// - 企鹅王的鹰弩 - (无描述)
            gift.add(1452073);// - 企鹅王的火焰之弓 - (无描述)
            break;
        case 2022573:// - 企鹅王的飞侠武器箱子 - 装着企鹅王的飞侠武器的箱子。
            gift.add(1332088);// - 企鹅王的暗影刃 - (无描述)
            gift.add(1472089);// - 企鹅王的黑守护拳套 - (无描述)
            break;
        case 2022574:// - 企鹅王的海盗武器箱子 - 装着企鹅王的海盗武器的箱子。
            gift.add(1482037);// - 企鹅王的双翼拳甲 - (拳甲)
            gift.add(1492038);// - 企鹅王的红杰克 - (短枪)
            break;
        case 2022575:// - 企鹅王的战士盔甲箱子 - 装着企鹅王的战士防具的箱子。
            gift.add(1040145);// - 企鹅王的金龙衣 - (上衣)
            gift.add(1041148);// - 企鹅王的红骑士甲 - (上衣)
            break;
        case 2022576:// - 企鹅王的魔法师盔甲箱子 - 装着企鹅王的魔法师防具的箱子。
            gift.add(1050155);// - 企鹅王的白魔力长袍 - (无描述)
            gift.add(1051191);// - 企鹅王的红贤者之袍 - (无描述)
            break;
        case 2022577:// - 企鹅王的弓箭手盔甲箱子 - 装着企鹅王的弓箭手防具的箱子。
            gift.add(1040146);// - 企鹅王的黑守护之服 - (无描述)
            gift.add(1041149);// - 企鹅王的褐守护之服 - (无描述)
            break;
        case 2022578:// - 企鹅王的飞侠盔甲箱子 - 装着企鹅王的飞侠防具的箱子。
            gift.add(1040147);// - 企鹅王的黑暗影之服 - (无描述)
            gift.add(1041150);// - 企鹅王的紫寂靜之服 - (无描述)
            break;
        case 2022579:// - 企鹅王的海盗盔甲箱子 - 装着企鹅王的海盗防具的箱子。
            gift.add(1052208);// - 企鹅王的了望手服装 - (无描述)
            break;
        case 2022580:// - 企鹅王的战士箱子 - 装着企鹅王的战士装备的箱子。
            gift.add(1072399);// - 企鹅王的黑铁头鞋 - (无描述)
            gift.add(1060134);// - 企鹅王的半白武裤 - (无描述)
            gift.add(1061156);// - 企鹅王的红骑士裙 - (无描述)
            break;
        case 2022581:// - 企鹅王的魔法师箱子 - 装着企鹅王的魔法师装备的箱子。
            gift.add(1072400);// - 企鹅王的黑守护鞋 - (无描述)
            break;
        case 2022582:// - 企鹅王的弓箭手箱子 - 装着企鹅王的弓箭手装备的箱子。
            gift.add(1072401);// - 企鹅王的红锦丝鞋 - (无描述)
            gift.add(1060135);// - 企鹅王的黑守护之裤 - (无描述)
            gift.add(1061157);// - 企鹅王的褐守护裤 - (无描述)
            break;
        case 2022583:// - 企鹅王的飞侠箱子 - 装着企鹅王的飞侠装备的箱子。
            gift.add(1072402);// - 企鹅王的蓝杨柳鞋 - (无描述)
            gift.add(1060136);// - 企鹅王的黑暗影之裤 - (无描述)
            gift.add(1061158);// - 企鹅王的紫寂靜裙 - (无描述)
            break;
        case 2022613:
            NPCScriptManager.getInstance().start(c, 9900007, 88);
        }
        if (gift.isEmpty()) {
            c.getPlayer().dropMessage(1, item + " 箱子尚未设置");
        } else {
            int rand = ThreadLocalRandom.current().nextInt(gift.size());
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, (short) slot, (short) 1, false);
            MapleInventoryManipulator.addById(c, ((Integer) gift.get(rand)).intValue(), (short) 1, (byte) 0);
            gift.clear();
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    // UseSummonBag 使用召唤包
    public static final void UseSummonBag(final SeekableLittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) {
        if (!chr.isAlive()) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);

        if (chr.getMapId() >= 910000000 && chr.getMapId() <= 910000022) {
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().dropMessage(5, "市场无法使用召唤包.");
            return;
        }
        if (toUse != null && toUse.getQuantity() >= 1 && toUse.getItemId() == itemId) {

            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);

            if (c.getPlayer().isGM() || !FieldLimitType.SummoningBag.check(chr.getMap().getFieldLimit())) {
                final List<Pair<Integer, Integer>> toSpawn = MapleItemInformationProvider.getInstance().getSummonMobs(itemId);

                if (toSpawn == null) {
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                MapleMonster ht;
                int type = 0;

                for (int i = 0; i < toSpawn.size(); i++) {
                    if (Randomizer.nextInt(99) <= toSpawn.get(i).getRight()) {
                        ht = MapleLifeFactory.getMonster(toSpawn.get(i).getLeft());
						if (ht.getId() == 9300166) {
							chr.spawnBomb();
						} else {
                            chr.getMap().spawnMonster_sSack(ht, chr.getPosition(), type);
                        }
                    }
                }
            }
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    // UseTreasureChest 使用宝箱
    public static final void UseTreasureChest(final SeekableLittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) {
        final short slot = slea.readShort();
        final int itemid = slea.readInt();

        final IItem toUse = chr.getInventory(MapleInventoryType.ETC).getItem((byte) slot);
        if (toUse == null || toUse.getQuantity() <= 0 || toUse.getItemId() != itemid) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        int reward;
        int keyIDforRemoval = 0;
        String box;

        switch (toUse.getItemId()) {
        case 4280000: // Gold box
            reward = RandomRewards.getInstance().getGoldBoxReward();
            keyIDforRemoval = 5490000;
            box = "金寶箱";
            break;
        case 4280001: // Silver box
            reward = RandomRewards.getInstance().getSilverBoxReward();
            keyIDforRemoval = 5490001;
            box = "銀寶箱";
            break;
        default: // Up to no good
            return;
        }

        // Get the quantity
        int amount = 1;
        switch (reward) {
        case 2000004:
            amount = 200; // Elixir
            break;
        case 2000005:
            amount = 100; // Power Elixir
            break;
        }
        if (chr.getInventory(MapleInventoryType.CASH).countById(keyIDforRemoval) > 0) {
            final IItem item = MapleInventoryManipulator.addbyId_Gachapon(c, reward, (short) amount);

            if (item == null) {
                chr.dropMessage(5, "請確認是否有金鑰匙或者你身上的空間滿了.");
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.ETC, (byte) slot, (short) 1, true);
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, keyIDforRemoval, 1, true, false);
            c.getSession().write(MaplePacketCreator.getShowItemGain(reward, (short) amount, true));

            if (GameConstants.gachaponRareItem(item.getItemId()) > 0) {
                World.Broadcast
                        .broadcastMessage(MaplePacketCreator.getGachaponMega("[" + box + "] " + c.getPlayer().getName(),
                                " : 從金寶箱中獲得", item, (byte) 2, c.getPlayer().getClient().getChannel()).getBytes());
            }
        } else {
            chr.dropMessage(5, "請確認是否有銀鑰匙或者你身上的空間滿了.");
            c.getSession().write(MaplePacketCreator.enableActions());
        }
    }

    public static final void UseCashItem(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        // c.getPlayer().updateTick(slea.readInt());
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();

        final IItem toUse = c.getPlayer().getInventory(MapleInventoryType.CASH).getItem(slot);
        if (toUse == null || toUse.getItemId() != itemId || toUse.getQuantity() < 1) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }

        boolean used = false, cc = false;

        switch (itemId) {
        case 5042000: // 豫园高级瞬移之石
            c.getPlayer().changeMap(701000200);
            used = true;
            break;
        case 5042001: // 高级瞬移之石
            c.getPlayer().changeMap(741000000);
            used = true;
            break;
        case 5043000: // NPC瞬移之石
        case 5043001: {
            final short questid = slea.readShort();
            final int npcid = slea.readInt();
            final MapleQuest quest = MapleQuest.getInstance(questid);

            if (c.getPlayer().getQuest(quest).getStatus() == 1 && quest.canComplete(c.getPlayer(), npcid)) {
                final int mapId = MapleLifeFactory.getNPCLocation(npcid);
                if (mapId != -1) {
                    final MapleMap map = c.getChannelServer().getMapFactory().getMap(mapId);
                    if (map.containsNPC(npcid) && !FieldLimitType.VipRock.check(c.getPlayer().getMap().getFieldLimit())
                            && !FieldLimitType.VipRock.check(map.getFieldLimit())
                            && c.getPlayer().getEventInstance() == null) {
                        c.getPlayer().changeMap(map, map.getPortal(0));
                    }
                    used = true;
                } else {
                    c.getPlayer().dropMessage(1, "发生未知错误.");
                }
            }
            break;
        }
        case 2320000: // 高级瞬移之石
        case 5041000: // 高级瞬移之石
        case 5040000: // 缩地石
        case 5040001: { // 可乐翅膀
            if (slea.readByte() == 0) { // Rocktype
                final MapleMap target = c.getChannelServer().getMapFactory().getMap(slea.readInt());
                if ((itemId == 5041000 && c.getPlayer().isRockMap(target.getId()))
                        || (itemId != 5041000 && c.getPlayer().isRegRockMap(target.getId()))) {
                    if (!FieldLimitType.VipRock.check(c.getPlayer().getMap().getFieldLimit())
                            && !FieldLimitType.VipRock.check(target.getFieldLimit())
                            && c.getPlayer().getEventInstance() == null) { // Makes sure this map doesn't have a forced
                                                                           // return map
                        c.getPlayer().changeMap(target, target.getPortal(0));
                        used = true;
                    }
                }
            } else {
                final MapleCharacter victim = c.getChannelServer().getPlayerStorage()
                        .getCharacterByName(slea.readMapleAsciiString());
                if (victim != null && !victim.isGM() && c.getPlayer().getEventInstance() == null
                        && victim.getEventInstance() == null) {
                    if (!FieldLimitType.VipRock.check(c.getPlayer().getMap().getFieldLimit()) && !FieldLimitType.VipRock
                            .check(c.getChannelServer().getMapFactory().getMap(victim.getMapId()).getFieldLimit())) {
                        if (itemId == 5041000
                                || (victim.getMapId() / 100000000) == (c.getPlayer().getMapId() / 100000000)) { // Viprock
                                                                                                                // or
                                                                                                                // same
                                                                                                                // continent
                            c.getPlayer().changeMap(victim.getMap(),
                                    victim.getMap().findClosestSpawnpoint(victim.getPosition()));
                            used = true;
                        }
                    }
                }
            }
            break;
        }
        case 5050000: { // 洗能力点卷轴

            // used = false;
            List<Pair<MapleStat, Integer>> statupdate = new ArrayList<Pair<MapleStat, Integer>>(2);
            final int apto = slea.readInt();
            final int apfrom = slea.readInt();

            if (apto == apfrom) {
                break; // Hack
            }
            final int job = c.getPlayer().getJob();
            final PlayerStats playerst = c.getPlayer().getStat();
            used = true;
            if ((apfrom == 0x2000) && (apto != 32768)) {
                c.sendPacket(MaplePacketCreator.enableActions());
                return;
            }
            if ((apfrom == 0x8000) && (apto != 0x2000)) {
                c.sendPacket(MaplePacketCreator.enableActions());
                return;
            }

            switch (apto) { // AP to
            case 256: // str
                if (playerst.getStr() >= 32767) {
                    used = false;
                }
                break;
            case 512: // dex
                if (playerst.getDex() >= 32767) {
                    used = false;
                }
                break;
            case 1024: // int
                if (playerst.getInt() >= 32767) {
                    used = false;
                }
                break;
            case 2048: // luk
                if (playerst.getLuk() >= 32767) {
                    used = false;
                }
                break;
            case 8192: // hp
                if (playerst.getMaxHp() >= 30000) {
                    used = false;
                }
                break;
            case 32768: // mp
                if (playerst.getMaxMp() >= 30000) {
                    used = false;
                }
                break;
            }
            switch (apfrom) { // AP to
            case 256: // str
                // if (playerst.getStr() <= 4 || (c.getPlayer().getJob() % 1000 / 100 == 1 &&
                // playerst.getStr() <= 35)) {
                if (playerst.getStr() <= 4) {
                    used = false;
                }
                break;
            case 512: // dex
                // if (playerst.getDex() <= 4 || (c.getPlayer().getJob() % 1000 / 100 == 3 &&
                // playerst.getStr() <= 25) || (c.getPlayer().getJob() % 1000 / 100 == 4 &&
                // playerst.getStr() <= 25) || (c.getPlayer().getJob() % 1000 / 100 == 5 &&
                // playerst.getStr() <= 20)) {
                if (playerst.getDex() <= 4) {
                    used = false;
                }
                break;
            case 1024: // int
                // if (playerst.getInt() <= 4 || (c.getPlayer().getJob() % 1000 / 100 == 2 &&
                // playerst.getInt() <= 20)) {
                if (playerst.getInt() <= 4) {
                    used = false;
                }
                break;
            case 2048: // luk
                if (playerst.getLuk() <= 4) {
                    used = false;
                }
                break;
            case 8192: // hp
                // if (playerst.getMaxMp() < ((c.getPlayer().getLevel() * 14) + 134) ||
                // c.getPlayer().getHpApUsed() <= 0 || c.getPlayer().getHpApUsed() >= 25000 ||
                // playerst.getMaxHp() < 1) {

                // if (playerst.getMaxHp() <= 30000) {
                if (playerst.getMaxHp() >= 30000) {
                    used = false;
                }
                break;
            case 32768: // mp
                // if (playerst.getMaxMp() < ((c.getPlayer().getLevel() * 14) + 134) ||
                // c.getPlayer().getHpApUsed() <= 0 || c.getPlayer().getHpApUsed() >= 25000) {
                // if (playerst.getMaxMp() <= 30000) {
                if (playerst.getMaxMp() >= 30000) {
                    used = false;
                }
                break;
            }
            if (used) {
                switch (apto) { // AP to
                case 256: { // str
                    final int toSet = playerst.getStr() + 1;
                    playerst.setStr((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.STR, toSet));
                    break;
                }
                case 512: { // dex
                    final int toSet = playerst.getDex() + 1;
                    playerst.setDex((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.DEX, toSet));
                    break;
                }
                case 1024: { // int
                    final int toSet = playerst.getInt() + 1;
                    playerst.setInt((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.INT, toSet));
                    break;
                }
                case 2048: { // luk
                    final int toSet = playerst.getLuk() + 1;
                    playerst.setLuk((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.LUK, toSet));
                    break;
                }
                case 8192: // hp
                    short maxhp = playerst.getMaxHp();

                    if (job == 0) { // Beginner
                        maxhp += Randomizer.rand(8, 12);
                    } else if ((job >= 100 && job <= 132) || (job >= 3200 && job <= 3212)) { // Warrior
                        ISkill improvingMaxHP = SkillFactory.getSkill(1000001);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp += Randomizer.rand(20, 25);
                        if (improvingMaxHPLevel >= 1) {
                            maxhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if ((job >= 200 && job <= 232) || (GameConstants.isEvan(job))) { // Magician
                        maxhp += Randomizer.rand(10, 20);
                    } else if ((job >= 300 && job <= 322) || (job >= 400 && job <= 434) || (job >= 1300 && job <= 1312)
                            || (job >= 1400 && job <= 1412) || (job >= 3300 && job <= 3312)) { // Bowman
                        maxhp += Randomizer.rand(16, 20);
                    } else if ((job >= 500 && job <= 522) || (job >= 3500 && job <= 3512)) { // Pirate
                        ISkill improvingMaxHP = SkillFactory.getSkill(5100000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp += Randomizer.rand(18, 22);
                        if (improvingMaxHPLevel >= 1) {
                            maxhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1500 && job <= 1512) { // Pirate
                        ISkill improvingMaxHP = SkillFactory.getSkill(15100000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp += Randomizer.rand(18, 22);
                        if (improvingMaxHPLevel >= 1) {
                            maxhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1100 && job <= 1112) { // Soul Master
                        ISkill improvingMaxHP = SkillFactory.getSkill(11000000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp += Randomizer.rand(36, 42);
                        if (improvingMaxHPLevel >= 1) {
                            maxhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1200 && job <= 1212) { // Flame Wizard
                        maxhp += Randomizer.rand(15, 21);
                    } else if (job >= 2000 && job <= 2112) { // Aran
                        maxhp += Randomizer.rand(40, 50);
                    } else { // GameMaster
                        maxhp += Randomizer.rand(50, 100);
                    }
                    maxhp = (short) Math.min(30000, Math.abs(maxhp));
                    c.getPlayer().setHpApUsed((short) (c.getPlayer().getHpApUsed() + 1));
                    playerst.setMaxHp(maxhp);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.MAXHP, (int) maxhp));
                    break;

                case 32768: // mp
                    short maxmp = playerst.getMaxMp();

                    if (job == 0) { // Beginner
                        maxmp += Randomizer.rand(6, 8);
                    } else if (job >= 100 && job <= 132) { // Warrior
                        maxmp += Randomizer.rand(5, 7);
                    } else if ((job >= 200 && job <= 232) || (GameConstants.isEvan(job))
                            || (job >= 3200 && job <= 3212)) { // Magician
                        ISkill improvingMaxMP = SkillFactory.getSkill(2000001);
                        int improvingMaxMPLevel = c.getPlayer().getSkillLevel(improvingMaxMP);
                        maxmp += Randomizer.rand(18, 20);
                        if (improvingMaxMPLevel >= 1) {
                            maxmp += improvingMaxMP.getEffect(improvingMaxMPLevel).getY() * 2;
                        }
                    } else if ((job >= 300 && job <= 322) || (job >= 400 && job <= 434) || (job >= 500 && job <= 522)
                            || (job >= 3200 && job <= 3212) || (job >= 3500 && job <= 3512)
                            || (job >= 1300 && job <= 1312) || (job >= 1400 && job <= 1412)
                            || (job >= 1500 && job <= 1512)) { // Bowman
                        maxmp += Randomizer.rand(10, 12);
                    } else if (job >= 1100 && job <= 1112) { // Soul Master
                        maxmp += Randomizer.rand(6, 9);
                    } else if (job >= 1200 && job <= 1212) { // Flame Wizard
                        ISkill improvingMaxMP = SkillFactory.getSkill(12000000);
                        int improvingMaxMPLevel = c.getPlayer().getSkillLevel(improvingMaxMP);
                        maxmp += Randomizer.rand(18, 20);
                        if (improvingMaxMPLevel >= 1) {
                            maxmp += improvingMaxMP.getEffect(improvingMaxMPLevel).getY() * 2;
                        }
                    } else if (job >= 2000 && job <= 2112) { // Aran
                        maxmp += Randomizer.rand(6, 9);
                    } else { // GameMaster
                        maxmp += Randomizer.rand(50, 100);
                    }
                    maxmp = (short) Math.min(30000, Math.abs(maxmp));
                    c.getPlayer().setHpApUsed((short) (c.getPlayer().getHpApUsed() + 1));
                    playerst.setMaxMp(maxmp);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.MAXMP, (int) maxmp));
                    break;
                }
                switch (apfrom) { // AP from
                case 256: { // str
                    final int toSet = playerst.getStr() - 1;
                    playerst.setStr((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.STR, toSet));
                    break;
                }
                case 512: { // dex
                    final int toSet = playerst.getDex() - 1;
                    playerst.setDex((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.DEX, toSet));
                    break;
                }
                case 1024: { // int
                    final int toSet = playerst.getInt() - 1;
                    playerst.setInt((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.INT, toSet));
                    break;
                }
                case 2048: { // luk
                    final int toSet = playerst.getLuk() - 1;
                    playerst.setLuk((short) toSet);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.LUK, toSet));
                    break;
                }
                case 8192: // HP
                    short maxhp = playerst.getMaxHp();
                    if (job == 0) { // Beginner
                        maxhp -= 12;
                    } else if (job >= 100 && job <= 132) { // Warrior
                        ISkill improvingMaxHP = SkillFactory.getSkill(1000001);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp -= 24;
                        if (improvingMaxHPLevel >= 1) {
                            maxhp -= improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 200 && job <= 232) { // Magician
                        maxhp -= 10;
                    } else if ((job >= 300 && job <= 322) || (job >= 400 && job <= 434) || (job >= 1300 && job <= 1312)
                            || (job >= 1400 && job <= 1412) || (job >= 3300 && job <= 3312)
                            || (job >= 3500 && job <= 3512)) { // Bowman, Thief
                        maxhp -= 15;
                    } else if (job >= 500 && job <= 522) { // Pirate
                        ISkill improvingMaxHP = SkillFactory.getSkill(5100000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp -= 15;
                        if (improvingMaxHPLevel > 0) {
                            maxhp -= improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1500 && job <= 1512) { // Pirate
                        ISkill improvingMaxHP = SkillFactory.getSkill(15100000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp -= 15;
                        if (improvingMaxHPLevel > 0) {
                            maxhp -= improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1100 && job <= 1112) { // Soul Master
                        ISkill improvingMaxHP = SkillFactory.getSkill(11000000);
                        int improvingMaxHPLevel = c.getPlayer().getSkillLevel(improvingMaxHP);
                        maxhp -= 27;
                        if (improvingMaxHPLevel >= 1) {
                            maxhp -= improvingMaxHP.getEffect(improvingMaxHPLevel).getY();
                        }
                    } else if (job >= 1200 && job <= 1212) { // Flame Wizard
                        maxhp -= 12;
                    } else if ((job >= 2000 && job <= 2112) || (job >= 3200 && job <= 3212)) { // Aran
                        maxhp -= 40;
                    } else { // GameMaster
                        maxhp -= 20;
                    }
                    c.getPlayer().setHpApUsed((short) (c.getPlayer().getHpApUsed() - 1));
                    playerst.setHp(maxhp);
                    playerst.setMaxHp(maxhp);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.HP, (int) maxhp));
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.MAXHP, (int) maxhp));
                    break;
                case 32768: // MP
                    short maxmp = playerst.getMaxMp();
                    if (job == 0) { // Beginner
                        maxmp -= 8;
                    } else if (job >= 100 && job <= 132) { // Warrior
                        maxmp -= 4;
                    } else if (job >= 200 && job <= 232) { // Magician
                        ISkill improvingMaxMP = SkillFactory.getSkill(2000001);
                        int improvingMaxMPLevel = c.getPlayer().getSkillLevel(improvingMaxMP);
                        maxmp -= 20;
                        if (improvingMaxMPLevel >= 1) {
                            maxmp -= improvingMaxMP.getEffect(improvingMaxMPLevel).getY();
                        }
                    } else if ((job >= 500 && job <= 522) || (job >= 300 && job <= 322) || (job >= 400 && job <= 434)
                            || (job >= 1300 && job <= 1312) || (job >= 1400 && job <= 1412)
                            || (job >= 1500 && job <= 1512) || (job >= 3300 && job <= 3312)
                            || (job >= 3500 && job <= 3512)) { // Pirate, Bowman. Thief
                        maxmp -= 10;
                    } else if (job >= 1100 && job <= 1112) { // Soul Master
                        maxmp -= 6;
                    } else if (job >= 1200 && job <= 1212) { // Flame Wizard
                        ISkill improvingMaxMP = SkillFactory.getSkill(12000000);
                        int improvingMaxMPLevel = c.getPlayer().getSkillLevel(improvingMaxMP);
                        maxmp -= 25;
                        if (improvingMaxMPLevel >= 1) {
                            maxmp -= improvingMaxMP.getEffect(improvingMaxMPLevel).getY();
                        }
                    } else if (job >= 2000 && job <= 2112) { // Aran
                        maxmp -= 5;
                    } else { // GameMaster
                        maxmp -= 20;
                    }
                    c.getPlayer().setHpApUsed((short) (c.getPlayer().getHpApUsed() - 1));
                    playerst.setMp(maxmp);
                    playerst.setMaxMp(maxmp);
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.MP, (int) maxmp));
                    statupdate.add(new Pair<MapleStat, Integer>(MapleStat.MAXMP, (int) maxmp));
                    break;
                }
                c.getSession().write(MaplePacketCreator.updatePlayerStats(statupdate, true, c.getPlayer().getJob()));
            }
            break;
        }
        case 5050001: // SP Reset (1st job)
        case 5050002: // SP Reset (2nd job)
        case 5050003: // SP Reset (3rd job)
        case 5050004: { // SP Reset (4th job)
            int skill1 = slea.readInt();
            int skill2 = slea.readInt();

            ISkill skillSPTo = SkillFactory.getSkill(skill1);
            ISkill skillSPFrom = SkillFactory.getSkill(skill2);

            if (skillSPTo.isBeginnerSkill() || skillSPFrom.isBeginnerSkill()) {
                break;
            }
            if ((c.getPlayer().getSkillLevel(skillSPTo) + 1 <= skillSPTo.getMaxLevel())
                    && c.getPlayer().getSkillLevel(skillSPFrom) > 0) {
                c.getPlayer().changeSkillLevel(skillSPFrom, (byte) (c.getPlayer().getSkillLevel(skillSPFrom) - 1),
                        c.getPlayer().getMasterLevel(skillSPFrom));
                c.getPlayer().changeSkillLevel(skillSPTo, (byte) (c.getPlayer().getSkillLevel(skillSPTo) + 1),
                        c.getPlayer().getMasterLevel(skillSPTo));
                used = true;
            }
            break;
        }
        /* case 5060000: { // Item Tag
            final IItem item = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(slea.readByte());

            if (item != null && item.getOwner().equals("")) {
                boolean change = true;
                for (String z : GameConstants.RESERVED) {
                    if (c.getPlayer().getName().indexOf(z) != -1 || item.getOwner().indexOf(z) != -1) {
                        change = false;
                    }
                }
                if (change) {
                    item.setOwner(c.getPlayer().getName());
                    c.getPlayer().forceReAddItem(item, MapleInventoryType.EQUIPPED);
                    used = true;
                }
            }
            break;
        } */
        case 5062000: { // miracle cube
            final IItem item = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((byte) slea.readInt());
            if (item != null && c.getPlayer().getInventory(MapleInventoryType.USE).getNumFreeSlot() >= 1) {
                final Equip eq = (Equip) item;
                if (eq.getState() >= 5) {
                    eq.renewPotential();
                    c.getSession().write(MaplePacketCreator.scrolledItem(toUse, item, false, true));
                    // c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.getPotentialEffect(c.getPlayer().getId(),
                    // eq.getItemId()));
                    c.getPlayer().forceReAddItem_NoUpdate(item, MapleInventoryType.EQUIP);
                    MapleInventoryManipulator.addById(c, 2430112, (short) 1, (byte) 0);
                    used = true;
                } else {
                    c.getPlayer().dropMessage(5, "确保你的设备有潜力.");
                }
            } else {
                c.getPlayer().dropMessage(5, "确保你有一个片段的空间.");
            }
            break;
        }
        case 5080000:
        case 5080001:
        case 5080002:
        case 5080003: {
            MapleLove love = new MapleLove(c.getPlayer(), c.getPlayer().getPosition(),
                    c.getPlayer().getMap().getFootholds().findBelow(c.getPlayer().getPosition()).getId(),
                    slea.readMapleAsciiString(), itemId);
            c.getPlayer().getMap().spawnLove(love);
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            break;

        }
        case 5201004: {
            int 豆豆数量 = 20;
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            c.getPlayer().dropMessage(5, "成功充值20豆豆！！");
            c.getPlayer().dropMessage(5, "正在刷新人物数据....请稍后...");
            c.getPlayer().gainBeans(豆豆数量);
            c.getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(c.getPlayer()));
            c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), 豆豆数量));
            c.getPlayer().getMap().removePlayer(c.getPlayer());
            c.getPlayer().getMap().addPlayer(c.getPlayer());
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().saveToDB(true, true);
            c.getPlayer().dropMessage(5, "人物数据刷新成功!");
            break;
        }
        case 5201001: {
            int 豆豆数量 = 500;
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            c.getPlayer().dropMessage(5, "成功充值500豆豆！！");
            c.getPlayer().dropMessage(5, "正在刷新人物数据....请稍后...");
            c.getPlayer().gainBeans(豆豆数量);
            c.getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(c.getPlayer()));
            c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), 豆豆数量));
            c.getPlayer().getMap().removePlayer(c.getPlayer());
            c.getPlayer().getMap().addPlayer(c.getPlayer());
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().saveToDB(true, true);
            c.getPlayer().dropMessage(5, "人物数据刷新成功!");

            break;
        }
        case 5201002: {
            int 豆豆数量 = 3000;
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            c.getPlayer().dropMessage(5, "成功充值3000豆豆！！");
            c.getPlayer().dropMessage(5, "正在刷新人物数据....请稍后...");
            c.getPlayer().gainBeans(豆豆数量);
            c.getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(c.getPlayer()));
            c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), 豆豆数量));
            c.getPlayer().getMap().removePlayer(c.getPlayer());
            c.getPlayer().getMap().addPlayer(c.getPlayer());
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().saveToDB(true, true);
            c.getPlayer().dropMessage(5, "人物数据刷新成功!");
            break;
        }
        case 5201005: {
            {
                int 豆豆数量 = 50;
                MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
                c.getPlayer().dropMessage(5, "成功充值50豆豆！！");
                c.getPlayer().dropMessage(5, "正在刷新人物数据....请稍后...");
                c.getPlayer().gainBeans(豆豆数量);
                c.getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(c.getPlayer()));
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), 豆豆数量));
                c.getPlayer().getMap().removePlayer(c.getPlayer());
                c.getPlayer().getMap().addPlayer(c.getPlayer());
                c.getSession().write(MaplePacketCreator.enableActions());
                c.getPlayer().saveToDB(true, true);
                c.getPlayer().dropMessage(5, "人物数据刷新成功!");
                break;
            }
        }
        case 5201000: {
            int 豆豆数量 = 2000;
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            c.getPlayer().dropMessage(5, "成功充值2000豆豆！！");
            c.getPlayer().dropMessage(5, "正在刷新人物数据....请稍后...");
            c.getPlayer().gainBeans(豆豆数量);
            c.getPlayer().getClient().getSession().write(MaplePacketCreator.getCharInfo(c.getPlayer()));
            c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), 豆豆数量));
            c.getPlayer().getMap().removePlayer(c.getPlayer());
            c.getPlayer().getMap().addPlayer(c.getPlayer());
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().saveToDB(true, true);
            c.getPlayer().dropMessage(5, "人物数据刷新成功!");
            break;
        }
        case 5520000: { // Karma
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((byte) slea.readInt());
            if (item != null && !ItemFlag.KARMA_EQ.check(item.getFlag()) && !ItemFlag.KARMA_USE.check(item.getFlag())) {
                if (itemId == 5520000 && MapleItemInformationProvider.getInstance().isKarmaEnabled(item.getItemId())
                        || MapleItemInformationProvider.getInstance().isPKarmaEnabled(item.getItemId())) {
                    byte flag = item.getFlag();
                    if (type == MapleInventoryType.EQUIP) {
                        flag |= ItemFlag.KARMA_EQ.getValue();
                    } else {
                        flag |= ItemFlag.KARMA_USE.getValue();
                    }
                    item.setFlag(flag);

                    c.getPlayer().forceReAddItem_Flag(item, type);
                    used = true;
                }
            }
            break;
        }
        case 5570000: { // Vicious Hammer
            slea.readInt(); // Inventory type, Hammered eq is always EQ.
            final Equip item = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP)
                    .getItem((byte) slea.readInt());
            // another int here, D3 49 DC 00
            if (item != null) {
                if (GameConstants.canHammer(item.getItemId())
                        && MapleItemInformationProvider.getInstance().getSlots(item.getItemId()) > 0
                        && item.getViciousHammer() <= 2) {
                    item.setViciousHammer((byte) (item.getViciousHammer() + 1));
                    item.setUpgradeSlots((byte) (item.getUpgradeSlots() + 1));

                    c.getPlayer().forceReAddItem(item, MapleInventoryType.EQUIP);
                    // c.getSession().write(MTSCSPacket.ViciousHammer(true, (byte)
                    // item.getViciousHammer()));
                    // c.getSession().write(MTSCSPacket.ViciousHammer(false, (byte) 0));
                    used = true;
                    cc = true;
                } else {
                    c.getPlayer().dropMessage(5, "你不得在这个物品上使用它.");
                    cc = true;
                }
            }

            break;
        }
        case 5610001:
        case 5610000: { // Vega 30
            slea.readInt(); // Inventory type, always eq
            final byte dst = (byte) slea.readInt();
            slea.readInt(); // Inventory type, always use
            final byte src = (byte) slea.readInt();
            used = UseUpgradeScroll(src, dst, (byte) 2, c, c.getPlayer(), itemId); // cannot use ws with vega but we
                                                                                   // dont care
            cc = used;
            break;
        }
        case 5060000: {
            IItem 道具取名 = null;
            int equipSlot = slea.readShort();
            道具取名 = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) (byte) equipSlot);
            c.getSession().write(MaplePacketCreator.serverNotice(5, "请将道具直接点在你需要刻名的装备上.只能刻上自己的名字"));
            if (道具取名 == null) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            道具取名.setOwner(c.getPlayer().getName());
            c.getSession().write(MaplePacketCreator.updateEquipSlot(道具取名));
            MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
            c.getSession().write(MaplePacketCreator.serverNotice(5, "道具刻名成功~！你已经拥有自己的专属装备了，恭喜啦！"));
            break;
        }
        case 5060001: { // Sealing Lock
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((byte) slea.readInt());
            // another int here, lock = 5A E5 F2 0A, 7 day = D2 30 F3 0A
            if (item != null && item.getExpiration() == -1) {
                byte flag = item.getFlag();
                flag |= ItemFlag.LOCK.getValue();
                item.setFlag(flag);

                c.getPlayer().forceReAddItem_Flag(item, type);
                used = true;
            }
            break;
        }
        case 5061000: { // Sealing Lock 7 days
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((byte) slea.readInt());
            // another int here, lock = 5A E5 F2 0A, 7 day = D2 30 F3 0A
            if (item != null && item.getExpiration() == -1) {
                byte flag = item.getFlag();
                flag |= ItemFlag.LOCK.getValue();
                item.setFlag(flag);
                item.setExpiration(System.currentTimeMillis() + (7 * 24 * 60 * 60 * 1000));

                c.getPlayer().forceReAddItem_Flag(item, type);
                used = true;
            }
            break;
        }
        case 5061001: { // Sealing Lock 30 days
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((byte) slea.readInt());
            // another int here, lock = 5A E5 F2 0A, 7 day = D2 30 F3 0A
            if (item != null && item.getExpiration() == -1) {
                byte flag = item.getFlag();
                flag |= ItemFlag.LOCK.getValue();
                item.setFlag(flag);
                long days = 0;
                switch (itemId) {
                case 5061001:
                    days = 30;
                }
                if (days > 0) {
                    item.setExpiration(System.currentTimeMillis() + (days * 24 * 60 * 60 * 1000));
                }
                c.getPlayer().forceUpdateItem(type, item);
                MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
                c.getPlayer().dropMessage(5, "使用封印之锁 物品ID: " + itemId + " 天数: " + days);
                c.getSession().write(MaplePacketCreator.enableActions());
            } else {
                c.getPlayer().dropMessage(1, "使用道具出现错误.");
            }

            // c.getPlayer().forceReAddItem_Flag(item, type);
            // used = true;
            break;
        }
        case 5061003: {
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((short) (byte) slea.readInt());
            if ((item != null) && (item.getExpiration() == -1L)) {
                short flag = (short) item.getFlag();
                flag = (short) (flag | ItemFlag.LOCK.getValue());
                item.setFlag((byte) flag);
                long days = 0L;
                switch (itemId) {
                case 5061003:
                    days = 365L;
                }
                if (days > 0L) {
                    item.setExpiration(System.currentTimeMillis() + days * 365L * 60L * 60L * 1000L);
                }
                c.getPlayer().forceUpdateItem(type, item);
                MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
                c.getPlayer().dropMessage(5, "使用封印之锁 物品ID: " + itemId + " 天数: " + days);
                c.getSession().write(MaplePacketCreator.enableActions());
            } else {
                c.getPlayer().dropMessage(1, "使用道具出现错误.");
            }
            break;
        }
        case 5061002: { // Sealing Lock 90 days
            final MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
            final IItem item = c.getPlayer().getInventory(type).getItem((byte) slea.readInt());
            // another int here, lock = 5A E5 F2 0A, 7 day = D2 30 F3 0A
            if (item != null && item.getExpiration() == -1) {
                byte flag = item.getFlag();
                flag |= ItemFlag.LOCK.getValue();
                item.setFlag(flag);
                long days = 0;
                switch (itemId) {
                case 5061002:
                    days = 90;
                }
                if (days > 0) {
                    item.setExpiration(System.currentTimeMillis() + (days * 24 * 60 * 60 * 1000));
                }
                c.getPlayer().forceUpdateItem(type, item);
                MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, itemId, 1, true, false);
                c.getPlayer().dropMessage(5, "使用封印之锁 物品ID: " + itemId + " 天数: " + days);
                c.getSession().write(MaplePacketCreator.enableActions());
            } else {
                c.getPlayer().dropMessage(1, "使用道具出现错误.");
            }
            // c.getPlayer().forceReAddItem_Flag(item, type);
            // used = true;
            break;
        }
        case 5060003: {// peanut
            IItem item = c.getPlayer().getInventory(MapleInventoryType.ETC).findById(4170023);
            if (item == null || item.getQuantity() <= 0) { // hacking{
                return;
            }
            if (getIncubatedItems(c)) {
                MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.ETC, item.getPosition(), (short) 1,
                        false);
                used = true;
            }
        }
            break;
        case 5070000: { // Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
                c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次.");
                break;
            }
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);
                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    ;
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5071000: { // Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
                c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次.");
                break;
            }
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);

                if (c.getPlayer().isPlayer()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5077000: { // 3 line Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
                c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次.");
                break;
            }
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final byte numLines = slea.readByte();
                if (numLines > 3) {
                    return;
                }
                final List<String> messages = new LinkedList<String>();
                String message;
                for (int i = 0; i < numLines; i++) {
                    message = slea.readMapleAsciiString();
                    if (message.length() > 65) {
                        break;
                    }
                    messages.add(c.getPlayer().getName() + " : " + message);
                }
                final boolean ear = slea.readByte() > 0;
                if (c.getPlayer().isPlayer() && messages.indexOf("幹") != -1 || messages.indexOf("豬") != -1
                        || messages.indexOf("笨") != -1 || messages.indexOf("靠") != -1 || messages.indexOf("腦包") != -1
                        || messages.indexOf("腦") != -1 || messages.indexOf("智障") != -1 || messages.indexOf("白目") != -1
                        || messages.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    World.Broadcast
                            .broadcastSmega(MaplePacketCreator.tripleSmega(messages, ear, c.getChannel()).getBytes());
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + messages);
                } else if (c.getPlayer().isGM()) {
                    World.Broadcast
                            .broadcastSmega(MaplePacketCreator.tripleSmega(messages, ear, c.getChannel()).getBytes());
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + messages);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5073000: { // Heart Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
                c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次.");
                break;
            }
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);

                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(2, sb.toString()));
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5074000: { // Skull Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            /*
             * if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
             * c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次."); break; }
             */
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);

                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.serverNotice(10, c.getChannel(), sb.toString(), ear).getBytes());
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.serverNotice(10, c.getChannel(), sb.toString(), ear).getBytes());
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5072000: { // Super Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須要10等以上才能使用.");
                break;
            }
            /*
             * if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
             * c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次."); break; }
             */
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);

                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.serverNotice(3, c.getChannel(), sb.toString(), ear).getBytes());
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.serverNotice(3, c.getChannel(), sb.toString(), ear).getBytes());
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5076000: { // Item Megaphone
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            /*
             * if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
             * c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次."); break; }
             */
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String message = slea.readMapleAsciiString();

                if (message.length() > 65) {
                    break;
                }
                final StringBuilder sb = new StringBuilder();
                addMedalString(c.getPlayer(), sb);
                sb.append(c.getPlayer().getName());
                sb.append(" : ");
                sb.append(message);

                final boolean ear = slea.readByte() > 0;

                IItem item = null;
                if (slea.readByte() == 1) { // item
                    byte invType = (byte) slea.readInt();
                    byte pos = (byte) slea.readInt();
                    item = c.getPlayer().getInventory(MapleInventoryType.getByType(invType)).getItem(pos);
                }
                if (c.getPlayer().isPlayer() && message.indexOf("幹") != -1 || message.indexOf("豬") != -1
                        || message.indexOf("笨") != -1 || message.indexOf("靠") != -1 || message.indexOf("腦包") != -1
                        || message.indexOf("腦") != -1 || message.indexOf("智障") != -1 || message.indexOf("白目") != -1
                        || message.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.itemMegaphone(sb.toString(), ear, c.getChannel(), item).getBytes());
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                } else if (c.getPlayer().isGM()) {
                    World.Broadcast.broadcastSmega(
                            MaplePacketCreator.itemMegaphone(sb.toString(), ear, c.getChannel(), item).getBytes());
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + message);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }
        case 5075000: // MapleTV Messenger
        case 5075001: // MapleTV Star Messenger
        case 5075002: { // MapleTV Heart Messenger
            c.getPlayer().dropMessage(5, "没有mapletvs广播消息.");
            break;
        }
        case 5075003:
        case 5075004:
        case 5075005: { // 爱心广播消息
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必須等級10級以上才可以使用.");
                break;
            }
            int tvType = itemId % 10;
            if (tvType == 3) {
                slea.readByte(); // who knows
            }
            boolean ear = tvType != 1 && tvType != 2 && slea.readByte() > 1; // for tvType 1/2, there is no byte.
            MapleCharacter victim = tvType == 1 || tvType == 4 ? null
                    : c.getChannelServer().getPlayerStorage().getCharacterByName(slea.readMapleAsciiString()); // for
                                                                                                               // tvType
                                                                                                               // 4,
                                                                                                               // there
                                                                                                               // is no
                                                                                                               // string.
            if (tvType == 0 || tvType == 3) { // doesn't allow two
                victim = null;
            } else if (victim == null) {
                c.getPlayer().dropMessage(1, "这个角色不是在频道里.");
                break;
            }
            String message = slea.readMapleAsciiString();
            World.Broadcast.broadcastSmega(MaplePacketCreator
                    .serverNotice(3, c.getChannel(), c.getPlayer().getName() + " : " + message, ear).getBytes());
            break;
        }
        case 5090100: // 请柬
        case 5090000: { // 消息
            final String sendTo = slea.readMapleAsciiString();
            final String msg = slea.readMapleAsciiString();
            c.getPlayer().sendNote(sendTo, msg);
            used = true;
            break;
        }
        case 5100000: { // 音乐盒
            c.getPlayer().getMap().broadcastMessage(MTSCSPacket.playCashSong(5100000, c.getPlayer().getName()));
            used = true;
            break;
        }
        case 5152049:// - 一次性隐形眼镜（银色） - 使用一次可以让眼睛变成#c银色#
        case 5152100:// - 一次性隐形眼镜（黑色） - 使用一次可以让眼睛变成#c黑色#
        case 5152101:// - 一次性隐形眼镜（蓝色） - 使用一次可以让眼睛变成#c蓝色#
        case 5152102:// - 一次性隐形眼镜（红色） - 使用一次可以让眼睛变成#c红色#
        case 5152103:// - 一次性隐形眼镜（绿色） - 使用一次可以让眼睛变成#c 绿色#
        case 5152104:// - 一次性隐形眼镜（棕色） - 使用一次可以让眼睛变成#c棕色#
        case 5152105:// - 一次性隐形眼镜（祖母绿色） - 使用一次可以让眼睛变成#c祖母绿色#
        case 5152106:// - 一次性隐形眼镜（紫色） - 使用一次可以让眼睛变成#c紫色#
        case 5152107: {// - 一次性隐形眼镜（紫水晶色） - 使用一次可以让眼睛变成#c紫水晶色#
            MapleCharacter chr = c.getPlayer();
            int color = (itemId - 5152100) * 100;
            if (chr.isGM()) {
                System.out.println("使用一次性隐形眼镜 - 道具: " + itemId + " 颜色: " + color);
            }
            if (color >= 0) {
                changeFace(chr, color);
                used = true;
            } else {
                chr.dropMessage(1, "使用一次性隐形眼镜出现错误.");
            }
            break; // 一次性隐形眼睛修复完成
        }
        case 5190001:
        case 5190002:
        case 5190003:
        case 5190004:
        case 5190005:
        case 5190006:
        case 5190007: // 宠物召唤技能
        case 5190008: // 宠物自言自语技能
        case 5190000: { // 捡道具技能
            final int uniqueid = (int) slea.readLong();
            MaplePet pet = c.getPlayer().getPet(0);
            int slo = 0;

            if (pet == null) {
                break;
            }
            if (pet.getUniqueId() != uniqueid) {
                pet = c.getPlayer().getPet(1);
                slo = 1;
                if (pet != null) {
                    if (pet.getUniqueId() != uniqueid) {
                        pet = c.getPlayer().getPet(2);
                        slo = 2;
                        if (pet != null) {
                            if (pet.getUniqueId() != uniqueid) {
                                break;
                            }
                        } else {
                            break;
                        }
                    }
                } else {
                    break;
                }
            }
            PetFlag zz = PetFlag.getByAddId(itemId);
            if (zz != null && !zz.check(pet.getFlags())) {
                pet.setFlags(pet.getFlags() | zz.getValue());
                c.getSession().write(PetPacket.updatePet(pet,
                        c.getPlayer().getInventory(MapleInventoryType.CASH).getItem((byte) pet.getInventoryPosition()),
                        true));
                c.getSession().write(MaplePacketCreator.enableActions());
                c.getSession().write(MTSCSPacket.changePetFlag(uniqueid, true, zz.getValue()));
                used = true;
            }
            break;
        }
        // 取消宠物行动
        case 5191000: // 取消捡道具功能
        case 5191001: // 取消自动服用药水功能
        case 5191002: // 取消扩大移动范围技能
        case 5191003: // 取消范围自动捡起功能
        case 5191004: // 取消捡起无所有权道具&金币功能
        {
            final int uniqueid = (int) slea.readLong();
            MaplePet pet = c.getPlayer().getPet(0);
            int slo = 0;

            if (pet == null) {
                break;
            }
            if (pet.getUniqueId() != uniqueid) {
                pet = c.getPlayer().getPet(1);
                slo = 1;
                if (pet != null) {
                    if (pet.getUniqueId() != uniqueid) {
                        pet = c.getPlayer().getPet(2);
                        slo = 2;
                        if (pet != null) {
                            if (pet.getUniqueId() != uniqueid) {
                                break;
                            }
                        } else {
                            break;
                        }
                    }
                } else {
                    break;
                }
            }
            PetFlag zz = PetFlag.getByDelId(itemId);
            if (zz != null && zz.check(pet.getFlags())) {
                pet.setFlags(pet.getFlags() - zz.getValue());
                c.getSession().write(PetPacket.updatePet(pet,
                        c.getPlayer().getInventory(MapleInventoryType.CASH).getItem((byte) pet.getInventoryPosition()),
                        true));
                c.getSession().write(MaplePacketCreator.enableActions());
                c.getSession().write(MTSCSPacket.changePetFlag(uniqueid, false, zz.getValue()));
                used = true;
            }
            break;
        }
        case 5170000: { // 取宠物名
            /* final int uniqueid = (int) slea.readLong(); */
            MaplePet pet = c.getPlayer().getPet(0);
            int slo = 0;

            if (pet == null) {
                break;
            }
            /*
             * if (pet.getUniqueId() != uniqueid) { pet = c.getPlayer().getPet(1); slo = 1;
             * if (pet != null) { if (pet.getUniqueId() != uniqueid) { pet =
             * c.getPlayer().getPet(2); slo = 2; if (pet != null) { if (pet.getUniqueId() !=
             * uniqueid) { break; } } else { break; } } } else { break; } }
             */
            String nName = slea.readMapleAsciiString();
            /*
             * for (String z : GameConstants.RESERVED) { if (pet.getName().indexOf(z) != -1
             * || nName.indexOf(z) != -1) { break; } }
             */
            // if (MapleCharacterUtil.canChangePetName(nName)) {
            pet.setName(nName);
            c.getSession().write(PetPacket.updatePet(pet,
                    c.getPlayer().getInventory(MapleInventoryType.CASH).getItem((byte) pet.getInventoryPosition()),
                    true));
            c.getSession().write(MaplePacketCreator.enableActions());
            c.getPlayer().getMap().broadcastMessage(MTSCSPacket.changePetName(c.getPlayer(), nName, slo));
            used = true;
            // }
            break;
        }
        // 宠物专用食品
        case 5240000:
        case 5240001:
        case 5240002:
        case 5240003:
        case 5240004:
        case 5240005:
        case 5240006:
        case 5240007:
        case 5240008:
        case 5240009:
        case 5240010:
        case 5240011:
        case 5240012:
        case 5240013:
        case 5240014:
        case 5240015:
        case 5240016:
        case 5240017:
        case 5240018:
        case 5240019:
        case 5240020:
        case 5240021:
        case 5240022:
        case 5240023:
        case 5240024:
        case 5240025:
        case 5240026:
        case 5240027:
        case 5240028: { // Pet food
            MaplePet pet = c.getPlayer().getPet(0);

            if (pet == null) {
                break;
            }
            if (!pet.canConsume(itemId)) {
                pet = c.getPlayer().getPet(1);
                if (pet != null) {
                    if (!pet.canConsume(itemId)) {
                        pet = c.getPlayer().getPet(2);
                        if (pet != null) {
                            if (!pet.canConsume(itemId)) {
                                break;
                            }
                        } else {
                            break;
                        }
                    }
                } else {
                    break;
                }
            }
            final byte petindex = c.getPlayer().getPetIndex(pet);
            pet.setFullness(100);
            if (pet.getCloseness() < 30000) {
                if (pet.getCloseness() + 100 > 30000) {
                    pet.setCloseness(30000);
                } else {
                    pet.setCloseness(pet.getCloseness() + 100);
                }
                if (pet.getCloseness() >= GameConstants.getClosenessNeededForLevel(pet.getLevel() + 1)) {
                    pet.setLevel(pet.getLevel() + 1);
                    c.getSession().write(PetPacket.showOwnPetLevelUp(c.getPlayer().getPetIndex(pet)));
                    c.getPlayer().getMap().broadcastMessage(PetPacket.showPetLevelUp(c.getPlayer(), petindex));
                }
            }
            c.getSession().write(PetPacket.updatePet(pet,
                    c.getPlayer().getInventory(MapleInventoryType.CASH).getItem(pet.getInventoryPosition()), true));
            c.getPlayer().getMap().broadcastMessage(c.getPlayer(),
                    PetPacket.commandResponse(c.getPlayer().getId(), (byte) 1, petindex, true, true), true);
            used = true;
            break;
        }
        case 5230000: { // 商店搜索器
            final int itemSearch = slea.readInt();
            final List<HiredMerchant> hms = c.getChannelServer().searchMerchant(itemSearch);
            if (hms.size() > 0) {
                c.getSession().write(MaplePacketCreator.getOwlSearched(itemSearch, hms));
                used = true;
            } else {
                c.getPlayer().dropMessage(1, "无法找到该项目.");
            }
            break;
        }
        case 5281001: // 传说中的花香
        case 5280001: // Gas Skill
        case 5281000: { // Passed gas
            Rectangle bounds = new Rectangle((int) c.getPlayer().getPosition().getX(),
                    (int) c.getPlayer().getPosition().getY(), 1, 1);
            MapleMist mist = new MapleMist(bounds, c.getPlayer());
            c.getPlayer().getMap().spawnMist(mist, 10000, true);
            c.getPlayer().getMap().broadcastMessage(
                    MaplePacketCreator.getChatText(c.getPlayer().getId(), "Oh no, I farted!", false, 1));
            c.getSession().write(MaplePacketCreator.enableActions());
            used = true;
            break;
        }
        case 5320000: { // 塔罗牌使用券
            String name = slea.readMapleAsciiString();
            String otherName = slea.readMapleAsciiString();
            slea.readInt();
            slea.readInt();
            int cardId = slea.readByte();
            slea.readShort();
            slea.readByte();
            // int comm = slea.readByte();
            int comm = Randomizer.rand(0, 6);
            PredictCardFactory pcf = PredictCardFactory.getInstance();
            PredictCardFactory.PredictCard Card = pcf.getPredictCard(cardId);
            // int commentId = Randomizer.nextInt(pcf.getCardCommentSize() + comm);
            // PredictCardFactory.PredictCardComment Comment =
            // pcf.getPredictCardComment(pcf.getCardCommentSize());
            PredictCardFactory.PredictCardComment Comment = pcf.getPredictCardComment(comm);
            // PredictCardFactory.PredictCardComment Comment =
            // pcf.getPredictCardComment(commentId);
            if ((Card == null) || (Comment == null)) {
                break;
            }
            c.getPlayer().dropMessage(5, "爱情占卜成功。");

            int love = Randomizer.rand(1, Comment.score) + 5;
            c.getSession().write(MTSCSPacket.show塔罗牌(name, otherName, love, cardId, Comment.effectType));
            used = true;
            break;
        }
        case 5370000: { // 黑板（7天权）
            if (c.getPlayer().getMapId() / 1000000 == 109) {
                c.getPlayer().dropMessage(1, "当前地图无法使用此道具");
            } else {
                c.getPlayer().setChalkboard(slea.readMapleAsciiString());
            }
            break;
        }
        case 5370001: { // 黑板（1天权）
            if (c.getPlayer().getMapId() / 1000000 == 910) {
                c.getPlayer().setChalkboard(slea.readMapleAsciiString());
            }
            break;
        }
        // case 5390000: // Diablo Messenger
        // case 5390001: // Cloud 9 Messenger
        // case 5390002: // Loveholic Messenger
        // case 5390003: // New Year Megassenger 1
        // case 5390004: // New Year Megassenger 2
        // case 5390005: // Cute Tiger Messenger
        case 5390000: // 炽热情景喇叭 - 使用它可以把你的形象显示在所有频道，伴随你的穿着显示在所有人的屏幕上，并有燃烧背景哦
        case 5390001: // 绚烂情景喇叭 - 使用它可以把你的形象显示在所有频道，伴随你的穿着显示在所有人的屏幕上，并有明亮背景哦
        case 5390002: // 爱心情景喇叭 - 使用它可以把你的形象显示在所有频道，伴随你的穿着显示在所有人的屏幕上，并有爱心背景哦
        case 5390003: // 新年庆祝喇叭1 - 使用它可以把你的形象显示在所有频道，伴随你的穿着显示在所有人的屏幕上，并有新年庆祝背景哦
        case 5390004: // 新年庆祝喇叭2 - 使用它可以把你的形象显示在所有频道，伴随你的穿着显示在所有人的屏幕上，并有新年庆祝背景哦
        case 5390005: // 小老虎情景喇叭 - 使用该道具,会出现小老虎背景,全服务器的人都可以看得见的可爱的情景喇叭哦!
        case 5390006: // 咆哮老虎情景喇叭 - 虎年专用情景喇叭,有老虎咆哮效果.全服务器的人都可以看得见的帅气的情景喇叭哦!
        case 5390007:
        case 5390008:
        case 5390009:
        case 5390010:
        case 5390011:
        case 5390012:
        case 5390013:
        case 5390014:
        case 5390015:
        case 5390016:
        case 5390017:
        case 5390018:
        case 5390019:
        case 5390020:
        case 5390021:
        case 5390022:
        case 5390023:
        case 5390024:
        case 5390025:
        case 5390030: { // Tiger Roar's Messenger
            if (c.getPlayer().getLevel() < 10) {
                c.getPlayer().dropMessage(5, "必须等级10级以上才可以使用.");
                break;
            }
            /*
             * if (!c.getPlayer().getCheatTracker().canAvatarSmega2()) {
             * c.getPlayer().dropMessage(6, "很抱歉為了防止刷廣,所以你每10秒只能用一次."); break; }
             */
            if (!c.getChannelServer().getMegaphoneMuteState()) {
                final String text = slea.readMapleAsciiString();
                if (text.length() > 55) {
                    break;
                }
                final boolean ear = slea.readByte() != 0;
                if (c.getPlayer().isPlayer() && text.indexOf("幹") != -1 || text.indexOf("豬") != -1
                        || text.indexOf("笨") != -1 || text.indexOf("靠") != -1 || text.indexOf("腦包") != -1
                        || text.indexOf("腦") != -1 || text.indexOf("智障") != -1 || text.indexOf("白目") != -1
                        || text.indexOf("白吃") != -1) {
                    c.getPlayer().dropMessage("說髒話是不禮貌的，請勿說髒話。");
                    c.getSession().write(MaplePacketCreator.enableActions());
                    return;
                }
                if (c.getPlayer().isPlayer()) {
                    World.Broadcast.broadcastSmega(MaplePacketCreator
                            .getAvatarMega(c.getPlayer(), c.getChannel(), itemId, text, ear).getBytes());
                    System.out.println("[玩家廣播頻道 " + c.getPlayer().getName() + "] : " + text);
                } else if (c.getPlayer().isGM()) {
                    World.Broadcast.broadcastSmega(MaplePacketCreator
                            .getAvatarMega(c.getPlayer(), c.getChannel(), itemId, text, ear).getBytes());
                    System.out.println("[ＧＭ廣播頻道 " + c.getPlayer().getName() + "] : " + text);
                }
                used = true;
            } else {
                c.getPlayer().dropMessage(5, "目前喇叭停止使用.");
            }
            break;
        }

        case 5450000: { // 包裹商人妙妙
            MapleShopFactory.getInstance().getShop(61).sendShop(c);
            used = true;
            break;
        }
        // 魔法沙
        case 5500001:
        case 5500002: {
            IItem item = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem(slea.readShort());
            MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
            int days = 20;
            if ((item != null) && (!GameConstants.isAccessory(item.getItemId())) && (item.getExpiration() > -1L)
                    && (!ii.isCash(item.getItemId())) && (System.currentTimeMillis()
                            + 8640000000L > item.getExpiration() + days * 24 * 60 * 60 * 1000L)) {
                boolean change = true;
                for (String z : GameConstants.RESERVED) {
                    if ((c.getPlayer().getName().indexOf(z) != -1) || (item.getOwner().indexOf(z) != -1)) {
                        change = false;
                    }
                }
                if (change) {
                    item.setExpiration(item.getExpiration() + days * 24 * 60 * 60 * 1000);
                    c.getPlayer().forceReAddItem(item, MapleInventoryType.EQUIPPED);
                    used = true;
                } else {
                    c.getPlayer().dropMessage(1, "此装备无法使用.");
                }
            }
            break;
        }
        default:
            if (itemId / 10000 == 512) {
                final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
                final String msg = ii.getMsg(itemId).replaceFirst("%s", c.getPlayer().getName()).replaceFirst("%s",
                        slea.readMapleAsciiString());
                c.getPlayer().getMap().startMapEffect(msg, itemId);

                final int buff = ii.getStateChangeItem(itemId);
                if (buff != 0) {
                    for (MapleCharacter mChar : c.getPlayer().getMap().getCharactersThreadsafe()) {
                        ii.getItemEffect(buff).applyTo(mChar);
                    }
                }
                used = true;
            } else if (itemId / 10000 == 510) {
                c.getPlayer().getMap().startJukebox(c.getPlayer().getName(), itemId);
                used = true;
            } else if (itemId == 5201000) {
                c.getPlayer().gainBeans(2000);
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), itemId));
                used = true;
            } else if (itemId == 5201001) {
                c.getPlayer().gainBeans(500);
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), itemId));
                used = true;
            } else if (itemId == 5201002) {
                c.getPlayer().gainBeans(3000);
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), itemId));
                used = true;
            } else if (itemId == 5201004) {
                c.getPlayer().gainBeans(40);
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), itemId));
                used = true;
            } else if (itemId == 5201005) {
                c.getPlayer().gainBeans(50);
                c.getSession().write(MaplePacketCreator.updateBeans(c.getPlayer().getId(), itemId));
                used = true;
            } else if (itemId / 10000 == 520) {
                final int mesars = MapleItemInformationProvider.getInstance().getMeso(itemId);
                if (mesars > 0 && c.getPlayer().getMeso() < (Integer.MAX_VALUE - mesars)) {
                    used = true;
                    if (Math.random() > 0.1) {
                        final int gainmes = Randomizer.nextInt(mesars);
                        c.getPlayer().gainMeso(gainmes, false);
                        c.getSession().write(MTSCSPacket.sendMesobagSuccess(gainmes));
                    } else {
                        c.getSession().write(MTSCSPacket.sendMesobagFailed());
                    }
                }
                /*
                 * } else if (itemId / 10000 == 562) { UseSkillBook(slot, itemId, c,
                 * c.getPlayer()); //this should handle removing
                 */
            } else if (itemId == 5530000) {
                NPCScriptManager.getInstance().start(c, 9900004, 10086);
                c.getSession().write(MaplePacketCreator.enableActions());
                break;
            } else if (itemId / 10000 == 553 && itemId != 5530000) {
                UseRewardItem(slot, itemId, c, c.getPlayer());// this too
            } else {
                System.out.println("Unhandled CS item : " + itemId);
                System.out.println(slea.toString(true));
            }
            break;
        }

        if (used) {
            MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.CASH, slot, (short) 1, false, true);
        }
        c.getSession().write(MaplePacketCreator.enableActions());
        if (cc) {
            if (!c.getPlayer().isAlive() || c.getPlayer().getEventInstance() != null
                    || FieldLimitType.ChannelSwitch.check(c.getPlayer().getMap().getFieldLimit())) {
                c.getPlayer().dropMessage(1, "自动换频道失败.");
                return;
            }
            c.getPlayer().dropMessage(5, "自动换频道。请等待.");
            c.getPlayer().changeChannel(c.getChannel() == ChannelServer.getChannelCount() ? 1 : (c.getChannel() + 1));
        }
    }

    public static final void Pickup_Player(final SeekableLittleEndianAccessor slea, MapleClient c,
            final MapleCharacter chr) {
        if (c.getPlayer().getPlayerShop() != null || c.getPlayer().getConversation() > 0
                || c.getPlayer().getTrade() != null) { // hack
            return;
        }
        chr.updateTick(slea.readInt());
        slea.skip(1); // [4] Seems to be tickcount, [1] always 0
        final Point Client_Reportedpos = slea.readPos();
        if (chr == null) {
            return;
        }
        final MapleMapObject ob = chr.getMap().getMapObject(slea.readInt(), MapleMapObjectType.ITEM);

        if (ob == null) {
            c.getSession().write(MaplePacketCreator.enableActions());
            return;
        }
        final MapleMapItem mapitem = (MapleMapItem) ob;
        final Lock lock = mapitem.getLock();
        lock.lock();
        try {
            if (mapitem.isPickedUp()) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            if (mapitem.getOwner() != chr.getId() && ((!mapitem.isPlayerDrop() && mapitem.getDropType() == 0)
                    || (mapitem.isPlayerDrop() && chr.getMap().getEverlast()))) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            if (!mapitem.isPlayerDrop() && mapitem.getDropType() == 1 && mapitem.getOwner() != chr.getId()
                    && (chr.getParty() == null || chr.getParty().getMemberById(mapitem.getOwner()) == null)) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            final double Distance = Client_Reportedpos.distanceSq(mapitem.getPosition());
            if (Distance > 2500) {
                chr.getCheatTracker().registerOffense(CheatingOffense.全图吸物_客户端, String.valueOf(Distance));
            } else if (chr.getPosition().distanceSq(mapitem.getPosition()) > 640000.0) {
                chr.getCheatTracker().registerOffense(CheatingOffense.全图吸物_服务端);
            }
            if (mapitem.getMeso() > 0) {
                if (chr.getParty() != null && mapitem.getOwner() != chr.getId()) {
                    final List<MapleCharacter> toGive = new LinkedList<MapleCharacter>();

                    for (MaplePartyCharacter z : chr.getParty().getMembers()) {
                        MapleCharacter m = chr.getMap().getCharacterById(z.getId());
                        if (m != null) {
                            toGive.add(m);
                        }
                    }
                    for (final MapleCharacter m : toGive) {
                        m.gainMeso(
                                mapitem.getMeso() / toGive.size()
                                        + (m.getStat().hasPartyBonus ? (int) (mapitem.getMeso() / 20.0) : 0),
                                true, true);
                    }
                } else {
                    chr.gainMeso(mapitem.getMeso(), true, true);
                }
                removeItem(chr, mapitem, ob);
            } else {
                if (MapleItemInformationProvider.getInstance().isPickupBlocked(mapitem.getItem().getItemId())) {
                    c.getSession().write(MaplePacketCreator.enableActions());
                    c.getPlayer().dropMessage(5, "这个项目不能被选上.");
                } else if (useItem(c, mapitem.getItemId())) {
                    removeItem(c.getPlayer(), mapitem, ob);
                } else if (MapleInventoryManipulator.checkSpace(c, mapitem.getItem().getItemId(),
                        mapitem.getItem().getQuantity(), mapitem.getItem().getOwner())) {
                    if (mapitem.getItem().getQuantity() >= 50
                            && GameConstants.isUpgradeScroll(mapitem.getItem().getItemId())) {
                        c.setMonitored(true); // hack check
                    }
                    if (MapleInventoryManipulator.addFromDrop(c, mapitem.getItem(), true,
                            mapitem.getDropper() instanceof MapleMonster)) {
                        removeItem(chr, mapitem, ob);
                    }
                } else {
                    c.getSession().write(MaplePacketCreator.getInventoryFull());
                    c.getSession().write(MaplePacketCreator.getShowInventoryFull());
                    c.getSession().write(MaplePacketCreator.enableActions());
                }
            }
        } finally {
            lock.unlock();
        }
    }

    public static final void Pickup_Pet(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        if (chr == null) {
            return;
        }
        final byte petz = (byte) c.getPlayer().getPetIndex((int) slea.readLong/* Int */());
        final MaplePet pet = chr.getPet(petz);
        slea.skip(1); // [4] Zero, [4] Seems to be tickcount, [1] Always zero
        chr.updateTick(slea.readInt());
        final Point Client_Reportedpos = slea.readPos();
        final MapleMapObject ob = chr.getMap().getMapObject(slea.readInt(), MapleMapObjectType.ITEM);

        if (ob == null || pet == null) {
            return;
        }
        final MapleMapItem mapitem = (MapleMapItem) ob;
        final Lock lock = mapitem.getLock();
        lock.lock();
        try {
            if (mapitem.isPickedUp()) {
                c.getSession().write(MaplePacketCreator.getInventoryFull());
                return;
            }
            if (mapitem.getOwner() != chr.getId() && mapitem.isPlayerDrop()) {
                return;
            }
            if (mapitem.getOwner() != chr.getId() && ((!mapitem.isPlayerDrop() && mapitem.getDropType() == 0)
                    || (mapitem.isPlayerDrop() && chr.getMap().getEverlast()))) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            if (!mapitem.isPlayerDrop() && mapitem.getDropType() == 1 && mapitem.getOwner() != chr.getId()
                    && (chr.getParty() == null || chr.getParty().getMemberById(mapitem.getOwner()) == null)) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            if ((mapitem.isPlayerDrop()) && (mapitem.getDropType() == 2) && (mapitem.getOwner() == chr.getId())) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            if ((mapitem.isPlayerDrop()) && (mapitem.getDropType() == 0) && (mapitem.getOwner() == chr.getId())
                    && (mapitem.getMeso() != 0)) {
                c.getSession().write(MaplePacketCreator.enableActions());
                return;
            }
            final double Distance = Client_Reportedpos.distanceSq(mapitem.getPosition());
            if (Distance > 10000 && (mapitem.getMeso() > 0 || mapitem.getItemId() != 4001025)) {
                chr.getCheatTracker().registerOffense(CheatingOffense.宠物全图吸物_客户端, String.valueOf(Distance));
            } else if (pet.getPos().distanceSq(mapitem.getPosition()) > 640000.0) {
                chr.getCheatTracker().registerOffense(CheatingOffense.宠物全图吸物_服务端);

            }

            if (mapitem.getMeso() > 0) {
                if (chr.getParty() != null && mapitem.getOwner() != chr.getId()) {
                    final List<MapleCharacter> toGive = new LinkedList<MapleCharacter>();
                    final int splitMeso = mapitem.getMeso() * 40 / 100;
                    for (MaplePartyCharacter z : chr.getParty().getMembers()) {
                        MapleCharacter m = chr.getMap().getCharacterById(z.getId());
                        if (m != null && m.getId() != chr.getId()) {
                            toGive.add(m);
                        }
                    }
                    for (final MapleCharacter m : toGive) {
                        m.gainMeso(splitMeso / toGive.size()
                                + (m.getStat().hasPartyBonus ? (int) (mapitem.getMeso() / 20.0) : 0), true);
                    }
                    chr.gainMeso(mapitem.getMeso() - splitMeso, true);
                } else {
                    chr.gainMeso(mapitem.getMeso(), true);
                }
                removeItem_Pet(chr, mapitem, petz);
            } else {
                if (MapleItemInformationProvider.getInstance().isPickupBlocked(mapitem.getItemId())
                        || mapitem.getItemId() / 10000 == 291) {
                    c.getSession().write(MaplePacketCreator.enableActions());
                } else if (useItem(c, mapitem.getItemId())) {
                    removeItem_Pet(chr, mapitem, petz);
                } else if (MapleInventoryManipulator.checkSpace(c, mapitem.getItemId(), mapitem.getItem().getQuantity(),
                        mapitem.getItem().getOwner())) {
                    if (mapitem.getItem().getQuantity() >= 50 && mapitem.getItemId() == 2340000) {
                        c.setMonitored(true); // hack check
                    }
                    MapleInventoryManipulator.addFromDrop(c, mapitem.getItem(), true,
                            mapitem.getDropper() instanceof MapleMonster);
                    removeItem_Pet(chr, mapitem, petz);
                }
            }
        } finally {
            lock.unlock();
        }
    }

    public static final boolean useItem(final MapleClient c, final int id) {
        if (GameConstants.isUse(id)) { // TO prevent caching of everything, waste of mem
            final MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
            final byte consumeval = ii.isConsumeOnPickup(id);

            if (consumeval > 0) {
                if (consumeval == 2) {
                    if (c.getPlayer().getParty() != null) {
                        for (final MaplePartyCharacter pc : c.getPlayer().getParty().getMembers()) {
                            final MapleCharacter chr = c.getPlayer().getMap().getCharacterById(pc.getId());
                            if (chr != null) {
                                ii.getItemEffect(id).applyTo(chr);
                            }
                        }
                    } else {
                        ii.getItemEffect(id).applyTo(c.getPlayer());
                    }
                } else {
                    ii.getItemEffect(id).applyTo(c.getPlayer());
                }
                c.getSession().write(MaplePacketCreator.getShowItemGain(id, (byte) 1));
                return true;
            }
        }
        return false;
    }

    public static final void removeItem_Pet(final MapleCharacter chr, final MapleMapItem mapitem, int pet) {
        mapitem.setPickedUp(true);
        chr.getMap().broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 5, chr.getId(), pet),
                mapitem.getPosition());
        chr.getMap().removeMapObject(mapitem);
        if (mapitem.isRandDrop()) {
            chr.getMap().spawnRandDrop();
        }
    }

    private static final void removeItem(final MapleCharacter chr, final MapleMapItem mapitem,
            final MapleMapObject ob) {
        mapitem.setPickedUp(true);
        chr.getMap().broadcastMessage(MaplePacketCreator.removeItemFromMap(mapitem.getObjectId(), 2, chr.getId()),
                mapitem.getPosition());
        chr.getMap().removeMapObject(ob);
        if (mapitem.isRandDrop()) {
            chr.getMap().spawnRandDrop();
        }
    }

    private static final void addMedalString(final MapleCharacter c, final StringBuilder sb) {
        final IItem medal = c.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -21);
        if (medal != null) { // Medal
            sb.append("<");
            sb.append(MapleItemInformationProvider.getInstance().getName(medal.getItemId()));
            sb.append("> ");
        }
    }

    private static final boolean getIncubatedItems(MapleClient c) {
        if (c.getPlayer().getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() < 2
                || c.getPlayer().getInventory(MapleInventoryType.USE).getNumFreeSlot() < 2
                || c.getPlayer().getInventory(MapleInventoryType.SETUP).getNumFreeSlot() < 2) {
            c.getPlayer().dropMessage(5, "请在您的库存中清理空间.");
            return false;
        }
        final int[] ids = { 2430091, 2430092, 2430093, 2430101, 2430102, // mounts
                2340000, // rares
                1152000, 1152001, 1152004, 1152005, 1152006, 1152007, 1152008, // toenail only comes when db is out.
                1000040, 1102246, 1082276, 1050169, 1051210, 1072447, 1442106, // blizzard
                3010019, // chairs
                1001060, 1002391, 1102004, 1050039, 1102040, 1102041, 1102042, 1102043, // equips
                1082145, 1082146, 1082147, 1082148, 1082149, 1082150, // wg
                2043704, 2040904, 2040409, 2040307, 2041030, 2040015, 2040109, 2041035, 2041036, 2040009, 2040511,
                2040408, 2043804, 2044105, 2044903, 2044804, 2043009, 2043305, 2040610, 2040716, 2041037, 2043005,
                2041032, 2040305, // scrolls
                2040211, 2040212, 1022097, // dragon glasses
                2049000, 2049001, 2049002, 2049003, // clean slate
                1012058, 1012059, 1012060, 1012061, // pinocchio nose msea only.
                1332100, 1382058, 1402073, 1432066, 1442090, 1452058, 1462076, 1472069, 1482051, 1492024, 1342009, // durability
                                                                                                                   // weapons
                                                                                                                   // level
                                                                                                                   // 105
                2049400, 2049401, 2049301 };
        // out of 1000
        final int[] chances = { 100, 100, 100, 100, 100, 1, 10, 10, 10, 10, 10, 10, 10, 5, 5, 5, 5, 5, 5, 5, 2, 10, 10,
                10, 10, 10, 10, 10, 10, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
                10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 10, 10, 10, 10, 10, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
                2, 1, 2, 1, 2 };
        int z = Randomizer.nextInt(ids.length);
        while (chances[z] < Randomizer.nextInt(1000)) {
            z = Randomizer.nextInt(ids.length);
        }
        int z_2 = Randomizer.nextInt(ids.length);
        while (z_2 == z || chances[z_2] < Randomizer.nextInt(1000)) {
            z_2 = Randomizer.nextInt(ids.length);
        }
        c.getSession().write(MaplePacketCreator.getPeanutResult(ids[z], (short) 1, ids[z_2], (short) 1));
        return MapleInventoryManipulator.addById(c, ids[z], (short) 1, (byte) 0)
                && MapleInventoryManipulator.addById(c, ids[z_2], (short) 1, (byte) 0);

    }

    public static final void OwlMinerva(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        final byte slot = (byte) slea.readShort();
        final int itemid = slea.readInt();
        final IItem toUse = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot);
        if (toUse != null && toUse.getQuantity() > 0 && toUse.getItemId() == itemid && itemid == 2310000) {
            final int itemSearch = slea.readInt();
            final List<HiredMerchant> hms = c.getChannelServer().searchMerchant(itemSearch);
            if (hms.size() > 0) {
                c.getSession().write(MaplePacketCreator.getOwlSearched(itemSearch, hms));
                MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, true, false);
            } else {
                c.getPlayer().dropMessage(1, "无法找到该项目.");
            }
        }
        c.getSession().write(MaplePacketCreator.enableActions());
    }

    public static final void SunziBF(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        slea.readInt();
        byte slot = (byte) slea.readShort();
        int itemid = slea.readInt();
        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
        IItem item = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot);
        if ((item == null) || (item.getItemId() != itemid) || (c.getPlayer().getLevel() > 255)) {
            // c.disconnect();
            return;
        }
        // int expGained = ii.getExpCache(itemid) * c.getChannelServer().getExpRate();
        int expGained = ii.getExpCache(itemid);
        c.getPlayer().gainExp(expGained, true, false, true);
        c.getSession().write(MaplePacketCreator.enableActions());
        MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
    }

//    public static final void HeiLong_BaoWuHe(final SeekableLittleEndianAccessor slea, final MapleClient c) {
//        byte slot = (byte) slea.readShort();
//        int itemId = slea.readInt();
//        if (c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot).getItemId() != itemId
//                || c.getPlayer().getInventory(MapleInventoryType.USE).countById(itemId) < 1) {
//            return;
//        }
//        MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
//        Pair<Integer, List<RewardItem>> rewards = ii.getItemReward(itemId);
//        for (RewardItem reward : rewards.getRight()) {
//            if (!MapleInventoryManipulator.checkSpace(c, reward.itemid, reward.quantity, "")) {
//                c.getSession().write(MaplePacketCreator.getShowInventoryFull());
//                c.getPlayer().dropMessage(5, "背包空间不足.");
//                // chr.dropMessage(6, "背包空间不足。");
//                //////// System.out.println("1");
//                break;
//                /*
//                 * }if (itemId == 2022615) { //地铁遗失物箱子 NPCScriptManager.getInstance().start(c,
//                 * 9330006); c.getSession().write(MaplePacketCreator.enableActions()); }if
//                 * (itemId == 2022618) { //地铁遗失物箱子 NPCScriptManager.getInstance().start(c,
//                 * 9330008); c.getSession().write(MaplePacketCreator.enableActions());}
//                 */
//            }
//            if (itemId == 2022615) { // 地铁遗失物箱子
//                NPCScriptManager.getInstance().start(c, 9900004, 2022615);
//                c.getSession().write(MaplePacketCreator.enableActions());
//                break;
//            }
//            if (itemId == 2022613) { // 法老王盒子1
//                // NPCScriptManager.getInstance().start(c, 9330008, 1);
//                c.getSession().write(MaplePacketCreator.enableActions());
//                break;
//            }
//            if (itemId == 2022618) { // 法老王盒子2
//                // NPCScriptManager.getInstance().start(c, 9330008, 2);
//                c.getSession().write(MaplePacketCreator.enableActions());
//                break;
//            }
//            if (itemId == 2022336) {
//                // NPCScriptManager.getInstance().start(c, 9020000, 1000); //打开NPC
//                // MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemId, 1,
//                // false, false);
//                c.getSession().write(MaplePacketCreator.enableActions());
//                return;
//            }
//            if ((Randomizer.nextInt(rewards.getLeft()) < reward.prob)) {// Is it even possible to get an item with prob
//                                                                        // 1?USE //消耗类的黑龙箱子 与 企鹅王的宝物盒的爆率设置
//                if (CashItemInfo.getInventoryType(reward.itemid) == MapleInventoryType.EQUIP) {
//                    IItem item = ii.getEquipById(reward.itemid);
//                    if (reward.period != -1) {
//                        item.setExpiration(System.currentTimeMillis() + (reward.period * 60 * 60 * 10));
//                        //////// System.out.println("2");
//                    }
//                    MapleInventoryManipulator.addFromDrop(c, item, false);
//                    c.getPlayer().dropMessage(5, "获得物品.");
//                } else {
//                    MapleInventoryManipulator.addById(c, reward.itemid, reward.quantity, (byte) 0);
//                    // //////System.out.println("4");
//                }
//                MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemId, 1, false, false);
//                //////// System.out.println("5");
//                if (reward.worldmsg != null) {
//                    String msg = reward.worldmsg;
//                    msg.replaceAll("/name", c.getPlayer().getName());
//                    msg.replaceAll("/item", ii.getName(reward.itemid));
//                    c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, msg));
//                    // //////System.out.println("6");
//                }
//                break;
//            }
//        }
//        c.getSession().write(MaplePacketCreator.enableActions());
//    }

    public static final void Owl(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        if (c.getPlayer().haveItem(5230000, 1, true, false) || c.getPlayer().haveItem(2310000, 1, true, false)) {
            if (c.getPlayer().getMapId() >= 910000000 && c.getPlayer().getMapId() <= 910000022) {
                c.getSession().write(MaplePacketCreator.getOwlOpen());
            } else {
                c.getPlayer().dropMessage(5, "只能在自由市场使用.");
                c.getSession().write(MaplePacketCreator.enableActions());
            }
        }
    }

    public static final int OWL_ID = 2; // don't change. 0 = owner ID, 1 = store ID, 2 = object ID

    public static final void UseSkillBook(final SeekableLittleEndianAccessor slea, final MapleClient c,
            final MapleCharacter chr) {
        slea.skip(4);
        final byte slot = (byte) slea.readShort();
        final int itemId = slea.readInt();
        final IItem toUse = chr.getInventory(MapleInventoryType.USE).getItem(slot);

        if (toUse == null || toUse.getQuantity() < 1 || toUse.getItemId() != itemId) {
            return;
        }
        final Map<String, Integer> skilldata = MapleItemInformationProvider.getInstance()
                .getSkillStats(toUse.getItemId());
        if (skilldata == null) { // Hacking or used an unknown item
            return;
        }
        boolean canuse = false, success = false;
        int skill = 0, maxlevel = 0;

        final int SuccessRate = skilldata.get("success");
        final int ReqSkillLevel = skilldata.get("reqSkillLevel");
        final int MasterLevel = skilldata.get("masterLevel");

        byte i = 0;
        Integer CurrentLoopedSkillId;
        for (;;) {
            CurrentLoopedSkillId = skilldata.get("skillid" + i);
            i++;
            if (CurrentLoopedSkillId == null) {
                break; // End of data
            }
            if (Math.floor(CurrentLoopedSkillId / 10000) == chr.getJob()) {
                final ISkill CurrSkillData = SkillFactory.getSkill(CurrentLoopedSkillId);
                if (chr.getSkillLevel(CurrSkillData) >= ReqSkillLevel
                        && chr.getMasterLevel(CurrSkillData) < MasterLevel) {
                    canuse = true;
                    if (Randomizer.nextInt(99) <= SuccessRate && SuccessRate != 0) {
                        success = true;
                        final ISkill skill2 = CurrSkillData;
                        chr.changeSkillLevel(skill2, chr.getSkillLevel(skill2), (byte) MasterLevel);
                    } else {
                        success = false;
                    }
                    MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, (short) 1, false);
                    break;
                } else { // Failed to meet skill requirements
                    canuse = false;
                }
            }
        }
        c.getSession().write(MaplePacketCreator.useSkillBook(chr, skill, maxlevel, canuse, success));
    }

    public static final void OwlWarp(final SeekableLittleEndianAccessor slea, final MapleClient c) {
        c.getSession().write(MaplePacketCreator.enableActions());
        if (c.getPlayer().getMapId() >= 910000000 && c.getPlayer().getMapId() <= 910000022 && c.getPlayer().getPlayerShop() == null) {
            final int id = slea.readInt();
            final int map = slea.readInt();
            if (map >= 910000001 && map <= 910000022) {
                final MapleMap mapp = c.getChannelServer().getMapFactory().getMap(map);
                c.getPlayer().changeMap(mapp, mapp.getPortal(0));
                HiredMerchant merchant = null;
                List<MapleMapObject> objects;
                switch (OWL_ID) {
                    case 0:
                        objects = mapp.getAllHiredMerchantsThreadsafe();
                        for (MapleMapObject ob : objects) {
                            if (ob instanceof IMaplePlayerShop) {
                                final IMaplePlayerShop ips = (IMaplePlayerShop) ob;
                                if (ips instanceof HiredMerchant) {
                                    final HiredMerchant merch = (HiredMerchant) ips;
                                    if (merch.getOwnerId() == id) {
                                        merchant = merch;
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    case 1:
                        objects = mapp.getAllHiredMerchantsThreadsafe();
                        for (MapleMapObject ob : objects) {
                            if (ob instanceof IMaplePlayerShop) {
                                final IMaplePlayerShop ips = (IMaplePlayerShop) ob;
                                if (ips instanceof HiredMerchant) {
                                    final HiredMerchant merch = (HiredMerchant) ips;
                                    if (merch.getStoreId() == id) {
                                        merchant = merch;
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    default:
                        final MapleMapObject ob = mapp.getMapObject(id, MapleMapObjectType.HIRED_MERCHANT);
                        if (ob instanceof IMaplePlayerShop) {
                            final IMaplePlayerShop ips = (IMaplePlayerShop) ob;
                            if (ips instanceof HiredMerchant) {
                                merchant = (HiredMerchant) ips;
                            }
                        }
                        break;
                }
                if (merchant != null) {
                    if (merchant.isOwner(c.getPlayer())) {
                        merchant.setOpen(false);
                        merchant.removeAllVisitors((byte) 16, (byte) 0);
                        c.getPlayer().setPlayerShop(merchant);
                        c.getSession().write(PlayerShopPacket.getHiredMerch(c.getPlayer(), merchant, false));
                    } else {
                        if (!merchant.isOpen() || !merchant.isAvailable()) {
                            c.getPlayer().dropMessage(1, "这家店在维修，请稍后.");
                        } else {
                            if (merchant.getFreeSlot() == -1) {
                                c.getPlayer().dropMessage(1, "这家店已经达到了最大容量，请稍后.");
                            } else if (merchant.isInBlackList(c.getPlayer().getName())) {
                                c.getPlayer().dropMessage(1, "你已被禁止从这家商店.");
                            } else {
                                c.getPlayer().setPlayerShop(merchant);
                                merchant.addVisitor(c.getPlayer());
                                c.getSession().write(PlayerShopPacket.getHiredMerch(c.getPlayer(), merchant, false));
                            }
                        }
                    }
                } else {
                    c.getPlayer().dropMessage(1, "这家店在维修，请稍后.");
                }
            }
        }
    }

    // changeFace 改变眼睛颜色
    private static void changeFace(MapleCharacter player, int color) {// 换眼色.
        if (player.getFace() % 1000 < 100) {
            player.setFace(player.getFace() + color);
        } else if ((player.getFace() % 1000 >= 100) && (player.getFace() % 1000 < 200)) {
            player.setFace(player.getFace() - 100 + color);
        } else if ((player.getFace() % 1000 >= 200) && (player.getFace() % 1000 < 300)) {
            player.setFace(player.getFace() - 200 + color);
        } else if ((player.getFace() % 1000 >= 300) && (player.getFace() % 1000 < 400)) {
            player.setFace(player.getFace() - 300 + color);
        } else if ((player.getFace() % 1000 >= 400) && (player.getFace() % 1000 < 500)) {
            player.setFace(player.getFace() - 400 + color);
        } else if ((player.getFace() % 1000 >= 500) && (player.getFace() % 1000 < 600)) {
            player.setFace(player.getFace() - 500 + color);
        } else if ((player.getFace() % 1000 >= 600) && (player.getFace() % 1000 < 700)) {
            player.setFace(player.getFace() - 600 + color);
        } else if ((player.getFace() % 1000 >= 700) && (player.getFace() % 1000 < 800)) {
            player.setFace(player.getFace() - 700 + color);
        }
        player.updateSingleStat(MapleStat.FACE, player.getFace());
        player.equipChanged();
    }
}
